首页 > 代码库 > 受控组件 & 非受控组件
受控组件 & 非受控组件
在 React 中表单组件可分为两类,受控与非受控组件.
一、 受控组件
设置了 value
的 <input>
是一个受控组件。 对于受控的 <input>
,渲染出来的 HTML 元素始终保持 value
属性的值。例如:
render() {
return <input type="text" value="http://www.mamicode.com/Hello"/>
}
上面的代码将渲染出一个值为 Hello!
的 input 元素。用户在渲染出来的元素里输入任何值都不起作用,因为 React 已经赋值为 Hello!
。如果想响应更新用户输入的值,就得使用 onChange
事件:
constructor(props) { super(props); this.state={value:‘Hello‘}; this.handleChange=this.handleChange.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } render() { var value = http://www.mamicode.com/this.state.value; return <input type="text" value=http://www.mamicode.com/{value} onChange={this.handleChange} />; }
上面的代码中,React 将用户输入的值更新到 <input>
组件的 value
属性。这样实现响应或者验证用户输入的界面就很容易了。
二、 非受控组件
没有设置 value
(或者设为 null
) 的 <input>
组件是一个非受控组件。对于非受控的 <input>
组件,渲染出来的元素直接反映用户输入。例如:
render() {
return <input type="text"/>
}
上面的代码将渲染出一个空值的输入框,用户输入将立即反应到元素上。和受控元素一样,使用 onChange
事件可以监听值的变化。
如果想给组件设置一个非空的初始值,可以使用 defaultValue
属性。例如:
render() {
return <input type="text" defaultValue="http://www.mamicode.com/Default Value">
}
上面的代码渲染出来的元素和受控组件一样有一个初始值,但这个值用户可以改变并会反应到界面上。同样地, 类型为 radio
、checkbox
的<input>
支持 defaultChecked
属性, <select>
支持 defaultValue
属性。
render() { return ( <div> <input type="radio" name="opt" defaultChecked /> Option 1 <input type="radio" name="opt" /> Option 2 <select defaultValue="http://www.mamicode.com/C"> <option value="http://www.mamicode.com/A">Apple</option> <option value="http://www.mamicode.com/B">Banana</option> <option value="http://www.mamicode.com/C">Cranberry</option> </select> </div> ); }
需要注意的是,默认值只适用于第一次渲染,在重渲染阶段将不会适用。
三、checkbox和radio
checkbox 和 radio 比较特殊, 如果在 onChange 事件中调用了 preventDefault ,那么浏览器不会更新 checked 状态,即便事实上组件的值已经 checked 或者 unchecked 了 。
class HelloWorld extends React.Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.state={checked:true};
}
handleChange(e){
e.preventDefault();
this.setState((prevState) => {
return {checked:!prevState.checked};
});
}
render(){
return (<div>
<input type="checkbox" checked={this.state.checked} onChange={this.handleChange} />点击我
<br/>{String(this.state.checked)}
</div>)
}
}
ReactDOM.render(<HelloWorld/>,document.body);
|
|
在上面的例子中,虽然this.state.checked的值已经改变,但是checkbox的值确没有变,解决这个问题有三种方法:
1) 避免调用e.preventDefault,比如将上例的e.preventDefault注释掉就可以了;
2) 在setTimeout中处理checked的修改
handleChange(e){
window.setTimeout(() => {
this.setState((prevState) => {
return {checked:!prevState.checked};
});
},0);
}
3) 使用click事件
受控组件 & 非受控组件