【React学习笔记】React的双向绑定(React State)

一、什么是双向绑定、为何须要双向绑定?

本人是先入坑的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双向数据绑定的流程就完成了。

三、小结

  1. 在react中要实现数据的双向绑定,须要经过state来实现,

    根据菜鸟解释,react将每一个组件都定义为状态机,经过state来改变和控制组件的状态。

  2. 使用state以前须要先初始化,而且在state中定义所须要用到的变量,

    这个相似于vue中使用前先要在data部分定义变量。

    (通常使用时能够不用预先定义变量,只有在变量绑定对象为<input> <textarea> <select>时才须要,具体内容能够参考react官网相关解释。)

  3. 直接对state进行赋值是无效的,须要使用setState方法来赋值,这样才能触发状态的改变,从而达到值传递的效果。


另外补充一点,在上述两个例子中都将handleChange方法都以箭头函数的方式进行定义,这是因为js的闭包致使的。

若是想将handleChange定义为普通方法,能够在构造函数中将this对象绑定到handleChange方法

constructor(props) {
        super(props);
        this.state = {
            myName: ""
        }
        this.handleChange = this.handleChange.bind(this)      // 将`this`对象绑定到`handleChange`方法
    }
相关文章
相关标签/搜索