非受控组件
在大多数情况下,我们推荐使用受控组件来实现表单。在受控组件中,表单数据由 React 组件负责处理。另外一个选择是不受控组件,其表单数据由 DOM 元素本身处理。要编写一个未控制组件,你可以使用一个 ref 来从 DOM 获得 表单值,而不是为每个状态更新编写一个事件处理程序。
render() { return (<input type="text" defaultValue="Tom" />) }
上面的代码中,input的值不随外部调用者的状态变化而变化,由自己的状态来管理值。此处如果使用value代替defaultValue,会发现输入框的值无法改变。
- 如果一个表单组件没有value props(单选按钮和复选按钮对应的是 checked props)时,就可以称为非受控组件;
- 使用defaultValue和defaultChecked来表示组件的默认状态;
- 通过 defaultValue和defaultChecked来设置组件的默认值,它仅会被渲染一次,在后续的渲染时并不起作用
import React, { Component } from 'react';
class UnControlled extends Component {
handleSubmit = (e) => {
console.log(e);
e.preventDefault();
console.log(this.name.value);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" ref={i => this.name = i} defaultValue="BeiJing" />
<button type="submit">Submit</button>
</form>
);
}
}
export default UnControlled;
受控组件
在书写React组件的过程中,指定value或checked值,组件渲染出来的状态始终是给定的value值。下面的示例中,通过给input指定value,把它和state结合在一起,再绑定onChange事件,输入框的值就会随着this.state.value的变化而变化,此时input受调用者控制。
handleOnClick = () => {
this.setState({
value: ++this.state.value
})
}
render(){
return (
<div>
<input type="text" value={this.state.value} />
<button onClick={this.handleOnClick}></button>
</div>
)
}
<input>
或<select>
都要绑定一个change事件;每当表单的状态发生变化,都会被写入组件的state中,这种组件在React中被称为受控组件;在受控组件中,组件渲染出的状态与它的value或者checked prop向对应.react通过这种方式消除了组件的局部状态,是的应用的整个状态可控.react官方同样推荐使用受控表单组件,总结下React受控组件更新state的流程:
- 1.可以通过初始state中设置表单的默认值;
- 2.每当表单的值发生变化时,调用onChange事件处理器;
- 3.事件处理器通过合成事件对象e拿到改变后的状态,并更新应用的state.
- 4.setState触发视图的重新渲染,完成表单组件值得更新
react中数据是单向流动的.从示例中,我们能看出来表单的数据来源于组件的state,并通过props传入,这也称为单向数据绑定.然后,我们又通过onChange事件处理器将新的表单数据写回到state,完成了双向数据绑定.
总结
受控制组件与非受控组件的区别可以用一句简单的话概括:React组件根据其自身的值是否被调用者传递的props完全控制,控制则为受控组件,否则非受控组件。
实际开发中我们并不提倡使用非受控组件,因为实际情况下我们需要更多的考虑表单验证、选择性的开启或者关闭按钮点击、强制输入格式等功能支持,而此时我们将数据托管到 React 中有助于我们更好地以声明式的方式完成这些功能。