受控组件
受控组件:通过 props 设置表单组件的值。如下通过 this.state.name 设置了 input,同时因为不同于 Vue 中 data 可以直接进行修改,this.state 不可直接修改,故需要提供修改后的响应事件 handleNameChange,将修改的值「推」到表单中。
class Form extends Component {
constructor() {
super();
this.state = {
name: '',
};
}
handleNameChange = (event) => {
this.setState({ name: event.target.value });
};
render() {
return (
<div>
<input
type="text"
value={this.state.name}
onChange={this.handleNameChange}
/>
</div>
);
}
}
这意味着数据(state)和界面(inputs)总是异步的。state 将值给 input,并且 input 向 Form 请求修改当前值。同时意味着表单组件能够立刻响应 input 的变化。
非控组件
class Form extends Component {
handleSubmitClick = () => {
const name = this._name.value;
// do something with `name`
}
render() {
return (
<div>
<input type="text" ref={input => this._name = input} />
<button onClick={this.handleSubmitClick}>Sign up</button>
</div>
);
}
}
非控组件通过 ref 获得输入的值,即将需要的时候才将 field 中值「提」出来。
总结
根据使用场景选择。如果表单很简单,也没有什么复杂的 UI 反馈,非控组件是完全 ok 的。
feature | uncontrolled | controlled |
---|---|---|
one-time value retrieval (e.g. on submit) | ✅ | ✅ |
validating on submit | ✅ | ✅ |
instant field validation | ❌ | ✅ |
conditionally disabling submit button | ❌ | ✅ |
enforcing input format | ❌ | ✅ |
several inputs for one piece of data | ❌ | ✅ |
dynamic inputs | ❌ | ✅ |
另外
官方针对表单给出了推荐方案 Formik。
如果你想寻找包含验证、追踪访问字段以及处理表单提交的完整解决方案,使用 Formik 是不错的选择。然而,它也是建立在受控组件和管理 state 的基础之上——所以不要忽视学习它们。