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剛開始確實會有些難受…)


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