受控组件
我们先来看一个例子
import React, { Component } from 'react'
export default class MyInput extends Component{
handleContentChange = (e)=>{
this.setState({
content: e.target.value
})
}
render(){
return(
<div>
<input
type="text"
value={this.state.value}
onChange={this.handleContentChange}
/>
</div>
)
}
}
我们要经常使用表单来搜集用户输入,例如<input><select><textearea>等元素都要绑定一个change事件,当表单的状态发生变化,就会触发onChange事件,更新组件的state。这种组件在React中被称为受控组件
,在受控组件中,组件渲染出的状态与他的value或checked属性相对应,react通过这种方式消除了组件的局部状态,使整个状态可控。react官方同样推荐使用受控表单组件。
受控组件更新state的流程:
- 可以通过初始state中设置表单的默认值
- 每当表单的值发生变化时,调用onChange事件处理器
- 事件处理器通过事件对象e拿到改变后的状态,并更新组件的state
- 一旦通过setState方法更新state,就会触发视图的重新渲染,完成表单组件的更新
react中数据是单项流动的,从示例中,我们看出来表单的数据来源于组件的state,并通过props传入,这也称为单向数据绑定。然后我们又通过onChange事件处理器将新的数据写回到state,完成了双向数据绑定。
非受控组件
如果一个表单组件没有value props(单选和复选按钮对应的是checked props)时,就可以称为非受控组件.
在非受控组件中,我们可以使用一个ref来从DOM获得表单值。而不是为每个状态更新编写一个事件处理程序。
例如,下面的代码在非受控组件中接收单个属性。
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={(input) => this.input = input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
非受控组件-默认值
在React的生命周期中,表单元素上的value属性将会覆盖DOM中的值。使用非受控组件时,通常你希望React可以为其制定初始值,但不再控制后续更新,解决这个问题的办法是你可以指定一个defaultValue属性而不是value。
同样,<input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked,<select> 和 <textarea> 支持 defaultValue.
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
defaultValue="Bob"
type="text"
ref={(input) => this.input = input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
由于非受控组件将真实数据保存在 DOM 中,因此在使用非受控组件时,更容易同时集成 React 和非 React 代码。如果你想快速而随性,这样做可以减小代码量。否则,你应该使用受控组件。