HTML 表单元素与 React 中的其他 DOM 元素有所不同,因为表单元素自然地保留了一些内部状态。例如,这个纯 HTML 表单接受一个单独的 name:
<form> <label> Name: <input type="text" name="name" /> </label> <input type="submit" value="Submit" /> </form>
该表单和 HTML 表单的默认行为一致,当用户提交此表单时浏览器会打开一个新页面。如果你希望 React 中保持这个行为,也可以工作。但是多数情况下,用一个处理表单提交并访问用户输入到表单中的数据的 JavaScript 函数也很方便。实现这一点的标准方法是使用一种称为“受控组件(controlled components)”的技术。
在 HTML 中,表单元素如 <input>
,<textarea>
和 <select>
表单元素通常保持自己的状态,并根据用户输入进行更新。而在 React 中,可变状态一般保存在组件的 state(状态) 属性中,并且只能通过 setState() 更新。
我们可以通过使 React 的 state 成为 “单一数据源原则” 来结合这两个形式。然后渲染表单的 React 组件也可以控制在用户输入之后的行为。这种形式,其值由 React 控制的输入表单元素称为“受控组件”。
例如,如果我们想使上一个例子在提交时记录名称,我们可以将表单写为受控组件:
class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ''}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="Submit" /> </form> ); } }
设置表单元素的 value 属性之后,其显示值将由 this.state.value
决定,以满足 React 状态的同一数据理念。每次键盘敲击之后会执行 handleChange
方法以更新 React 状态,显示值也将随着用户的输入改变。
由于 value
属性设置在我们的表单元素上,显示的值总是 this.state.value
,以满足 state 状态的同一数据理念。由于 handleChange
在每次敲击键盘时运行,以更新 React state(状态),显示的值将更新为用户的输入。
对于受控组件来说,每一次 state(状态) 变化都会伴有相关联的处理函数。这使得可以直接修改或验证用户的输入。比如,如果我们希望强制 name 的输入都是大写字母,可以这样来写 handleChange
方法:
handleChange(event) { this.setState({value: event.target.value.toUpperCase()}); }
在 受控组件 上指定值 prop
可防止用户更改输入,除非您希望如此。 如果你已经指定了一个 value
,但是输入仍然是可编辑的,你可能会意外地把 value
设置为undefined
或 null
。
以下代码演示了这一点。 (输入首先被锁定,但在短暂的延迟后可以编辑。)
ReactDOM.render(<input value="hi" />, mountNode); setTimeout(function() { ReactDOM.render(<input value={null} />, mountNode); }, 1000);
有时使用受控组件有些乏味,因为你需要为每一个可更改的数据提供事件处理器,并通过 React 组件管理所有输入状态。当你将已经存在的代码转换为 React 时,或将 React 应用程序与非 React 库集成时,这可能变得特别烦人。在这些情况下,您可能需要使用不受控的组件,用于实现输入表单的替代技术。
本文作者:前端小毛
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!