【React】3、受控组件与非受控组件(vue和react的双向绑定分别是怎么实现的?)
系列文章目录
- React入门与概览(JSX语法)
- 面向组件编程——组件实例的三大核心属性state、props和refs超详解
- 受控组件与非受控组件(vue和react的双向绑定分别是怎么实现的?)
文章目录
- 系列文章目录
- 受控组件和非受控组件
-
-
-
- 理解
- 示例效果
- 非受控组件编码
- 受控组件编码
-
-
受控组件和非受控组件
理解
包含表单的组件分类
- 受控组件
- 非受控组件
示例效果
需求: 定义一个包含表单的组件
输入用户名密码后,点击登录提示输入信息
非受控组件编码
<script type="text/babel"> class Login extends React.Component { render() { return ( <form action="" onSubmit={this.handleSubmit}> 用户名:<input ref={currentNode => this.username = currentNode} type="text" name="username" /> 密码:<input ref={currentNode => this.password = currentNode} type="password" name="password" /> {/* form中的button默认提交,点击后触发表单提交事件onSubmit */} <button>登录</button> </form> ) } // 对input(以及其他的一些输入型DOM)中输入的数据现用现取,就是非受控组件 // handleSubmit函数中直接取出input中输入的数据(现用现取) handleSubmit = (event) => { event.preventDefault() // 阻止默认事件(阻止表单提交) const { username, password } = this alert(`你输入的用户名是${username.value},你输入的密码是${password.value}`) } } // 渲染组件 ReactDOM.render(<Login />, document.getElementById('test')) </script>
受控组件编码
<script type="text/babel"> class Login extends React.Component { // 初始化状态 state = { username: '123', password: '' } render() { return ( <form action="" onSubmit={this.handleSubmit} > {/* 输入类的DOM都可以绑定onChange事件,当DOM内容改变时触发该事件, 调用onChange指定的回调(this.saveUsername) */} 用户名:<input value={this.state.username} onChange{this.saveUsername} type="text" name="username" /> 密码:<input onChange={this.savePassword} type="password" name="password" /> {/* form中的button默认提交,点击后触发表单提交事件onSubmit */} <button>登录</button> </form> ) } /* 对input(以及其他的一些输入型DOM)中输入的数据维护到组件的state(状态)中, 等需要用的时候才取出,这就是受控组件 数据被onChange函数监听,只要输入型DOM数据一改变就触发onChange中指定的回调函数 回调函数saveUsername和savePassword中对改变的数据进行保存,保存到state中,需要使用的时候才取出。 */ /* 受控和不受控取决于value是受state控制还是dom自己控制, 受state控制的就是受控组件,不受state控制的是非受控组件 */ handleSubmit = (event) => { event.preventDefault() // 阻止默认事件(阻止表单提交) const { username, password } = this.state alert(`你输入的用户名是${username},你输入的密码是${password}`) } saveUsername = (event) => { this.setState({ username: event.target.value }) } savePassword = (event) => { this.setState({ password: event.target.value }); } } ReactDOM.render(<Login />, document.getElementById('test')) </script>
可以看出,
受控组件
的原理类似vue的vue-model双向绑定
,DOM中username
的值改变时调用saveUsername
函数,将当前值传入state
中存放;state
中的值改变时,DOM中username
被绑定到value={this.state.username}
一起改变。
其实,
vue
官方文档也对v-model做出了解释,v-model不过是vue封装的语法糖,它负责监听用户的输入事
件以更新数据
,并对一些极端场景进行一些特殊处理。也就是说,
react中的受控组件
与vue中的v-model
的原理其实都差不多,都是监听用户的输入事件以做出数据的更新(本例中指的是onChange
监听事件,绑定saveUsername
回调函数,在回调中将对数据的更新保存到state
中)。