react中的受控表单输入和非受控表单输入
大家可能见过很多文章表述过,“你不应该使用 setState
”,“refs
是不好的”,这很矛盾,那么选择的标准是什么呢?怎样才能做好这件事?
可以说,表单是一个web应用程序的核心,在react
中表单处理也很重要。
下面就来讲述一下,这两种处理的区别和和这两种处理方式的使用场景。
非受控
非受控型输入就像传统的`HTML`表单输入
复制代码
class Form extends Component{
render(){
<div>
<input type="text"/>
</div>
}
}
复制代码
他们记住你输入的内容。之后,你可以使用 ref
获取他们的值,
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>
);
}
}
复制代码
换句话说,你必须在需要的时候从表单中获取值。
这是执行表单输入最简单的方法。但是同样这种方式不是那么强大。
受控
一个受控制的输入接受它的当前值,以及一个更改该值的回调。你可以说这是一种“React way
”(这并不意味着你应该一直使用它)。
<input value={someValue} onChange={handleChange} />
复制代码
但是输入的值必须存在于某个state
中。通常,呈现输入的组件(也就是表单组件)会保存它的state
:
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>
);
}
}
复制代码
每次输入新字符时,都会调用handleNameChange
。它接受输入的新值,并将其设置到 state
中。
这种方式将值及时的告诉表单组件,而不需要显示获取输入值,表单组件总是能及时获取最新值,这意味着你的数据和UI是同步的,也意味着表单组件可以立刻响应输入的变化。
下面是一些常用此处理方式的场景
- 就地反馈,比如表单验证
- 禁用按钮,所有数据都是有效数据
- 强制执行特定的输入格式,比如信用卡号
当然,如果你觉得使用非受控方式会更加简单,那么就使用非受控方式吧!
如何使元素受控
当然,还有其他的表单元素。比如复选框,选框,文本区域。
如果你通过 a prop
设置一个表单元素的值,它就会变成“受控的”。
但是,每个表单元素都有不同的设置值的工具
元素 | 值 | 改变回调 | 在回调中的新职 |
---|---|---|---|
<input type="text" /> |
value=”string” | onChange | event.target.value |
<input type="checkbox" /> |
checked={boolean} | onChange | event.target.checked |
<input type="radio" /> |
checked={boolean} | onChange | event.target.checked |
<textarea /> |
value=”string” | onChange | event.target.value |
<select /> |
value=”option value” | onChange | event.target.value |
结论
受控表单域和非受控表单域都有优点,评估你的具体情况并选择合适的方法——适合你的就足够了。
如果你的表单在UI反馈方面非常简单,不受控制的参考是完全没问题的。你不必去听各种各样的文章说什么是“不好的”。
场景 | 非受控 | 受控 |
---|---|---|
一次性值检索 | ||
提交时验证 | ||
即时表单验证字段 | ||
有条件地禁用提交按钮 | ||
强制格式化输入 | ||
一条数据多个输入 | ||
动态输入 |
翻译自 Controlled and uncontrolled form inputs in React don’t have to be complicated