react 组件之受控 VS 非受控

976 阅读2分钟

受控

一个受控组件的 value 是由props 的 value 来决定,通过 onChange 回调来向父组件通知数据变更。父组件通过 onChange 回调管理自己的state 并将新的 value 通过 props 传给该(受控)组件。总结下 React 受控组件更新 state 的流程:

1. 表单默认值通过在父组件的初始 state 中设置
2. 每当表单的值发生变化时,调用onChange 事件处理
3. 事件处理器拿到改变后的状态,更新应用的 state
4. setState 触发视图的重新渲染,更新表单组件的值

例如,我们想在点击按钮的的时候做一些操作,比如打印出 input 的 value:

<input type="text" onChange={e => this.setState({ value: e.target.value })} value={this.state.value} />
<button onClick={() => console.log(this.state.value)}>打印</button>

由于在表单 input 上设置了 value 属性, 因此打印的值将始终为 this.state.value 并随用户输入而更新。

对于受控组件来说,每个state突变都有一个相关的处理函数。这使得修改或验证用户输入变得简单。

非受控

1. 如果一个表单组件没有 value props, 就可称为非受控组件
2. 使用 defaultValue来表示组件的默认状态,它仅会被渲染一次,在后续的渲染中不起作用

一般会在初始渲染时给 DOM 节点一个 defaultValue, 之后的数据交由 DOM 节点自行管理,组件外需要该节点数据的时候一般通过表单 API 获取或者使用 refs 属性直接获取:


<input type="text" defaultValue="1234" ref={this.input} />

console.log(this.input.value);

对比受控组件和非受控组件

当我们不需要对数据的变更进行实时操作的时候使用非受控组件,相反,使用受控组件。

a. 性能上的问题

有时使用受控组件会很麻烦,因为你需要为数据变化的每种方式都编写事件处理函数,并通过一个React组件传递所有的输入state。当业务变更时,我们可能需要更改很多onChange事件,这就很烦了。

b. 使用受控组件需要为每一个组件绑定一个onChange事件,当然,某些情况下可以用一个事件处理器来处理多个表单域的的 onChange 事件。

handleChange(event, name) {
    this.setState({ 
        [name]: event.target.value
    })
}

demo 戳这里