本文正在参加「金石计划」
受控组件
-
组件同时渲染表单和控制用户输入逻辑
-
表单数据是由 React 组件来管理
-
state 接管表单元素(如
<input>、<textarea>和<select>)的 value,setState更新value、<input>、<textarea>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("提交的名字: " + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> 名字: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="提交" /> </form> ); } }
<select> 多选
<select multiple={true} value={['B', 'C']}>
-
处理多个输入
- 每个元素添加
name属性 - 处理函数根据
event.target.name的值选择要执行的操作
class Reservation extends React.Component { constructor(props) { super(props); this.state = { isGoing: true, numberOfGuests: 2, }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(event) { const target = event.target; const value = target.type === "checkbox" ? target.checked : target.value; const name = target.name; this.setState({ [name]: value, }); } render() { return ( <form> <label> 参与: <input name="isGoing" type="checkbox" checked={this.state.isGoing} onChange={this.handleInputChange} /> </label> <br /> <label> 来宾人数: <input name="numberOfGuests" type="number" value={this.state.numberOfGuests} onChange={this.handleInputChange} /> </label> </form> ); } } - 每个元素添加
缺点
- 受控组件需要为数据变化的每种方式都编写事件处理函数
- 当你将之前的代码库转换为 React 或将 React 应用程序与非 React 库集成时比较麻烦
非受控组件
-
表单数据将交由 DOM 节点来处理
-
不是为每个状态更新都编写数据处理函数
-
使用 ref 来从 DOM 节点中获取表单数据
class NameForm extends React.Component { constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); this.input = React.createRef(); } handleSubmit(event) { alert("A name was submitted: " + this.input.current.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" ref={this.input} />{" "} </label> <input type="submit" value="Submit" /> </form> ); } } -
默认值
<input defaultValue="Bob" type="text" /> -
文件输入
始终是一个非受控组件,因为它的值只能由用户设置,而不能通过代码控制
class FileInput extends React.Component { constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); this.fileInput = React.createRef(); } handleSubmit(event) { event.preventDefault(); alert(`Selected file - ${this.fileInput.current.files[0].name}`); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Upload file: <input type="file" ref={this.fileInput} /> </label> <br /> <button type="submit">Submit</button> </form> ); } } ReactDOM.render(<FileInput />, document.getElementById("root"));
如何选择
-
受控组件
-
每次改变都会调用onCahnge函数
-
数据推送给
form表单 -
输入的值改变的时候表单组件会立即响应
- 实时校验
- 提交按钮判断表单的值是否可以点击
- 强制输入符合规则的值
-
如何选择
特点 非受控 受控 提交取值 ✅ ✅ 提交校验 ✅ ✅ 实时校验 ❌ ✅ 根据条件判断按钮状态 ❌ ✅ 强制格式化表单的值 ❌ ✅ 一条数据多个输入框 ❌ ✅ 动态输入 ❌ ✅