表单中的受控组件和非受控组件
受控组件
在 HTML 中,表单元素(如<input>
、 <textarea>
和 <select>
)之类的表单元素通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()
来更新。
也就是说在组件内部的表单数据通常保存在state中,表单中的数据交给state对象管理
<script type="text/babel"> //受控组件,表单中的数据交给state管理 class Demo extends React.Component{ constructor(){ super() this.state={ name:"tom" } } render(){ return <div> <input type="text" value={this.state.name}/> </div> } } ReactDOM.render(<Demo/>,document.getElementById("app")) </script>
表单中的value和state是同步关系
<script type="text/babel"> //受控组件,表单中的数据交给state管理 class Demo extends React.Component{ constructor(){ super() this.state={ name:"tom" } //this的绑定 this.change=this.change.bind(this) } change(e){ //修改state状态 this.setState({ name:e.target.value }) } render(){ return <div> <p>{this.state.name}</p> <input type="text" value={this.state.name} onChange={this.change}/> </div> } } ReactDOM.render(<Demo/>,document.getElementById("app")) </script>
此时我们可以看到表单中的数据和state保持着同步的关系,修改表单中的数据,那么state中的数据也会随之改变
非受控组件
在大多数情况下,我们推荐使用 受控组件 来处理表单数据。在一个受控组件中,表单数据是由 React 组件来管理的。另一种替代方案是使用非受控组件,这时表单数据将交由 DOM 节点来处理。
也就是说表单中的数据交给DOM处理
要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以 使用 ref 来从 DOM 节点中获取表单数据。
<script type="text/babel"> //非受控组件,表单中的数据交给dom管理 class Demo extends React.Component{ constructor(){ super() this.state={ name:"tom" } } componentDidMount(){ console.log(this) } render(){ return <div> <p>{this.state.name}</p> {/*当render函数执行的时候,它将会给组件实例对象上去挂载一个input属性*/} <input ref={(input)=>{this.input=input}} type="text" /> </div> } } ReactDOM.render(<Demo/>,document.getElementById("app")) </script>
在控制台可以查看到,挂载的input属性
此时我们可以这样拿到input中的value值
componentDidMount(){ console.log(this.input.value) } render(){ return <div> <p>{this.state.name}</p> {/*当render函数执行的时候,它将会给组件实例对象上去挂载一个input属性*/} <input ref={(input)=>{this.input=input}} type="text" value='hello' /> </div> }
此时就可以输出value中的值