受控组件
在React官网有给出这样的简述:原文链接
在 HTML 中,表单元素(如<input>
、<textarea>
和<select>
)通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用setState()
来更新。
我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
下面就举一个input输入框的例子来进一步了解下:
import React, { Component, Fragment } from 'react'
export default class Demohooks extends Component {
constructor(props) {
super(props);
this.state = {
controllValue: 0,
}
}
onChangeInput = (e) => {
this.setState({
controllValue: e.target.value
})
}
render() {
return (
<Fragment>
<h1>受控组件</h1>
<div>{this.state.controllValue}</div>
用户名:<input value={null} onChange={this.onChangeInput} />
</Fragment>
)
}
}
效果大致展示:
个人理解:
- 每当输入框的输入内容发生变化时,都会被写入到组件的state中,这种组件在React中被理解为受控组件。
- 受控组件的值,始终是由React的state驱动的。
- 这种组件的数据是由React组件进行管理的,所以在大多数情况下,官方推荐使用受控组件。
接下来让我们去了解下受控组件更新state的简要流程:
- 首先通过state设置输入框的默认值
- 当输入框的值发生变化时,调用onChange事件处理器
- 事件处理器通过合成事件对象 e 拿到改变后的数据,并且更新应用的state
- setState触发视图的重新渲染,完成数据的更新展示。
受控组件缺陷:
通过上面的例子,感觉受控组件很不错,因为输出框的值都是由React组件进行管理,不会出现很乱的情况,但也正是因为全部由React去管理,当我们有多个输入框,或者多个这种组件时,我们如果想同时获取到全部的值就必须每个都要编写事件处理函数,这会让我们的代码看着很臃肿,所以为了解决这种情况,出现了非受控组件。
非受控组件
在官网的简述为:原文链接
要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以 使用 ref来从 DOM 节点中获取表单数据。
因为非受控组件将真实数据储存在 DOM 节点中,所以在使用非受控组件时,有时候反而更容易同时集成 React 和非 React 代码。如果你不介意代码美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件。
从上面的简述中可以知道,非受控组件是利用DOM节点,下面就让举个例子进一步了解下:
import React, { Component } from 'react'
export default class Demohooks extends Component {
onSubmit = (event) => {
event.preventDefault();
const { inputName, password } = this;
console.log(inputName.value)
console.log(password.value)
}
render() {
return (
<div>
<form onSubmit={this.onSubmit}>
用户名:<input ref={c => this.inputName = c} /> <br />
密码:<input ref={c => this.password = c} /> <br />
<button>登录</button>
</form>
</div>
)
}
}
效果大致展示为:
- 输入框输入的值,存储在了DOM节点中
- 然后通过ref来获取该DOM节点取值
- 现用现取
总结:页面中所有输入类的DOM如果是现用现取的称为非受控组件,而通过setState将输入的值维护到了state中,需要时再从state中取出,这里的数据就受到了state的控制,称为受控组件。