React学习之旅Part7:React绑定事件和使用setState()修改state的数据、React实现双向数据绑定

一、绑定事件

在React中 所绑定的事件的名称都是由React提供的 因此 事件名称必须按照一定的规范
名称的首字母必须是大写的(即小驼峰命名法) 例如onClickonMouseEnter

且在为事件绑定函数的时候 必须用花括号包裹 而不能为字符串类型
例如:

<button onClick={function(){console.log("aaa")}}>click me</button>

但行内式不太方便 可以将函数进行抽离
像这样:

import React from 'react';

export default class Hello extends React.Component
{
    constructor()
    {
        super();
        this.state={}
    }

    render()
    {
        return <div>
            hello
            <hr/>
            <button onClick={this.myClick}>click me</button>
        </div>
    }

    // 组件内部的实例方法
    myClick()
    {
        console.log("aaa")
    }
}

需要注意的是:在调用方法的时候 要用this来指定 因为是在组件的内部调用自己的方法
加上this 代表将组件内的实例方法的引用交给绑定的事件
不能带有括号() 否则当React解析到该方法的调用时 该方法会被直接执行

但更标准的语法是使用【箭头函数】:

箭头函数是匿名的function函数(即没有函数名的函数)
在箭头函数内部 this永远指向外部this 而不是指向调用者 由此避免了一些作用域的问题

像这样:

import React from 'react';

export default class Hello extends React.Component
{
    constructor()
    {
        super();
        this.state={}
    }

    render()
    {
        return <div>
            hello
            <hr/>
            <button onClick={() => this.myClick()}>click me</button>
        </div>
    }

    // 将匿名函数指向myClick
    myClick = () => {
        console.log("aaa")
    }
}

在箭头函数里写入方法的调用
并将方法写成箭头函数的形式 并赋值一个具体的函数名以供调用

还可以传参

render()
{
    return <div>
        bindEvent
        <hr/>
        <button onClick={() => this.myClick("帅哥")}>click me</button>
    </div>
}

myClick = (arg1) => {
    console.log("我是" +arg1)
}

二、修改state数据

在React中 若想为state中的数据重新赋值 不能使用this.state.xxx=yyy
而应该调用React提供的setState()来修改 比如this.setState({xxx:yyy})

在React中推荐使用this.setState()修改状态值

如下案例 点击按钮修改展示的文本内容:

import React from 'react';

export default class Hello extends React.Component
{
    constructor()
    {
        super();
        this.state={
            msg:"Hello World"
        }
    }

    render()
    {
        return <div>
            <button onClick={() => this.myClick("帅哥")}>click me</button>
            <hr/>
            <h3>{this.state.msg}</h3>
        </div>
    }

    myClick = (arg1) => {
        this.setState(
            {msg:"Hello "+arg1}
        )
    }
}

需要注意的是:

  • 若state里有多个数据 在setState的时候只会将对应的state状态更新 而不会覆盖原本的其它state状态
  • this.setState()方法是异步执行的 但支持回调函数
    在方法后添加一个回调函数作为参数即可:this.setState({},callback())

三、数据绑定

在React中 可以绑定文本框与state的值
但只支持单向数据绑定state中的值的改变会实时更新到页面上
但页面上的值的改变不会实时改变state中的值

若只是将state数据绑定给文本框 却不设置onChange处理函数 那么文本框将会是个只读的文本框 无法输入任何数据
当为文本框绑定value值后 要么提供readOnly只读属性 要么提供onChange处理函数

import React from 'react';

export default class Hello extends React.Component
{
    constructor()
    {
        super();
        this.state={
            msg:"Hello World"
        }
    }

    render()
    {
        return <div>
            bindEvent
            <hr/>
            <button onClick={() => this.myClick("帅哥😎")}>click me</button>
            <hr/>
            <h3>{this.state.msg}</h3>
            <hr/>
            <input type="text" value={this.state.msg} onChange={() => this.inputChanged()}/>
        </div>
    }

    // 每当文本框内容改变 即调用该方法
    inputChanged = () => {
        console.log("dsadsad")
    }

    // 将匿名函数指向myClick
    myClick = (arg1) => {
        console.log("我是" +arg1)
        this.setState(
            {msg:"Hello Piconjo"+arg1},
            function(){console.log(this.state.msg)}
        )
    }
}

React并没有这种页面上的值实时反馈到state中的自动同步机制

为了实现该功能 在React中 需要手动监听文本框的onChange事件 然后在事件中拿到最新的文本框内的值 然后自己调用this.setState()方法 手动将最新的值同步到state中

1、手动监听文本框的onChange事件
<input type="text" value={this.state.msg} onChange={() => this.inputChanged()}/>

inputChanged = () => {
        console.log("dsadsad")
    }
2、在事件中拿到最新的文本框内的值

有两种方法可以实现:
方法一:通过事件参数e
e.target.value获取value属性

<input type="text" value={this.state.msg} onChange={(e) => this.inputChanged(e)}/>

inputChanged = (e) => {
   console.log(e.target.value)
}

方法二:通过ref引用
React和Vue一样 支持ref ref即元素的引用(reference)
只不过在React中 获取ref时 无需加上美元符号$
像这样即可:this.refs.引用名

给元素添加引用:

<input type="text" value={this.state.msg} onChange={() => this.inputChanged()} ref="input"/>

inputChanged = () => {
    console.log(this.refs.input.value)
}
3、手动将最新的值同步到state中
inputChanged = (e) => {
    console.log(e.target.value)
    console.log(this.refs.input.value)

    this.setState({
        msg:e.target.value
    })
}

这样 即可实现双向数据绑定了

(用React的话 实现数据双向绑定会麻烦写 需要自己实现部分功能
Vue的v-model自带了双向数据绑定 用习惯了再用React刚开始确实会有些难受…)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章