一、什么是双向绑定、为何须要双向绑定?
本人是先入坑的vue,因此在开发时已经习惯了vue的自动双向绑定。javascript
什么是双向绑定呢?html
在没有前端框架以前的开发时光中,咱们都是直接操做页面的DOM元素(element)的。将某个变量赋值到某个页面元素时都是一次性的操做,在此以后变量值的修改并不会影响页面元素的内容变化;而页面元素(好比input框)的内容变动之后,也不会使对应变量的值发生变化,咱们须要经过document.getElementById()
的方法获取到页面元素,而后再根据元素对象的value
获取变化之后的值再手动处理。前端
在vue中,框架已经帮咱们自动实现了双向绑定,任何一方(哪怕是页面上纯显示的)也会自动变化。(如下代码中,变量name
的变化会直接反应到input框中,而input框中值得修改也会反向引发name
变量的值变化。)vue
<!-- Vue中一个最简单的双向绑定示例 --> <template> <div> <el-input v-model=“name” /> </div> </template> <script> export default { data() { return { name: "", } }, } </script>
而到了react,发现并无双向绑定的功能,有点懊糟。java
NameShow.js import React from 'react'; class NameShow extends React.Component { myName = "" // 定义myName变量 render() { return ( <div> {/*尝试将myName变量绑定到input框上*/} <input value={this.myName}/> {/*获取myName,并直接显示在页面上*/} <div>My Name Is {this.myName}</div> </div> ) } } export default NameShow
将以上组件引入APP中并添加到页面上启动,发现不只没法双向绑定,甚至连修改input框的内容都没有任何反应,并且控制台有警告显示。大概的意思是value是只读的,值的修改必须经过onChange事件来修改。react
因此添加一个onChange
事件的handle方法handleChange
之后再次启动。前端框架
NameShow.js import React from 'react'; class NameShow extends React.Component { myName = "" // 定义myName变量 handleChange = (event) => { // 此处需使用箭头函数,不然方法中的this将会识别为undefined console.log(event.target.value) this.myName = event.target.value } render() { return ( <div> {/*尝试将myName变量绑定到input框上*/} <input value={this.myName} onChange={this.handleChange}/> {/*获取myName,并直接显示在页面上*/} <div>My Name Is {this.myName}</div> </div> ) } } export default NameShow
在输入框中输入内容之后,发现控制台有反应,正常拿到了修改之后的值,可是输入框和下面显示的内容却依旧没有变化。闭包
二、React不支持双向绑定?非也
react并非不支持双向绑定,而是双向绑定须要咱们本身来实现。这时候就是react中的一个重要概念登场了——React State。框架
在菜鸟教程中的解释是这样的:React 把组件当作是一个状态机(State Machines)。经过与用户的交互,实现不一样状态,而后渲染 UI,让用户界面和数据保持一致。函数
如今回到上面那个例子,进行一下改造,由使用类成员变量myName
改成使用state
中的myName
变量。
NameShow2.js import React from 'react'; class NameShow2 extends React.Component { constructor(props) { super(props); this.state = { // 注意1:此处需先对state进行初始化,否则编译会报错 myName: "" // 注意2:此处须要将变量在state中进行定义,不然会报警告 } } handleChange = (event) => { console.log(event.target.value) // this.state.myName = event.target.value // 注意3:此处直接赋值是无效的,必定要使用this的setState方法 this.setState( {myName: event.target.value} ) } render() { return ( <div> {/*尝试将myName变量绑定到input框上*/} <input value={this.state.myName} onChange={this.handleChange}/> {/*获取myName,并直接显示在页面上*/} <div>My Name Is {this.state.myName}</div> </div> ) } } export default NameShow2
将以上组件引入APP中并添加到页面上启动,并在input框填入内容,发现下面的显示也同步改变了,而且控制台也有输出。
到此,一个简单的react双向数据绑定的流程就完成了。
三、小结
-
在react中要实现数据的双向绑定,须要经过state来实现,
根据菜鸟解释,react将每一个组件都定义为状态机,经过state来改变和控制组件的状态。
-
使用state以前须要先初始化,而且在state中定义所须要用到的变量,
这个相似于vue中使用前先要在
data
部分定义变量。(通常使用时能够不用预先定义变量,只有在变量绑定对象为
<input>
<textarea>
<select>
时才须要,具体内容能够参考react官网相关解释。) -
直接对state进行赋值是无效的,须要使用
setState
方法来赋值,这样才能触发状态的改变,从而达到值传递的效果。
另外补充一点,在上述两个例子中都将handleChange
方法都以箭头函数的方式进行定义,这是因为js的闭包致使的。
若是想将handleChange
定义为普通方法,能够在构造函数中将this
对象绑定到handleChange
方法
constructor(props) { super(props); this.state = { myName: "" } this.handleChange = this.handleChange.bind(this) // 将`this`对象绑定到`handleChange`方法 }