react組件中事件處理的幾種寫法,幾種寫法的區(qū)別,bind(this)傳自定義的參數(shù)

react組件中事件處理的幾種寫法,幾種寫法的區(qū)別,bind(this)傳自定義的參數(shù)

一、在React元素綁定事件要注意的兩點
  1. 在React中事件的命名要采用駝峰命名法,而不是原生dom中的小寫,如:onclick要寫成onClick, onchange 要寫成onChange
  2. 響應(yīng)事件的函數(shù)要以對象的形式賦值,而不是以dom字符串的形式,如:
   //在 dom中:
    <button onclick="clickMe()">不服點我</button>
   //在React中
    <button onClick={clickButton}>不服點我</button> //clickButton是一個函數(shù)

注意:React的事件是合成事件,并不是原生的dom事件,在dom中可以通過返回false來阻止事件的默認(rèn)行為,但是在react中必須顯示調(diào)用事件對象的e.preventDefault來阻止事件的默認(rèn)行為,除了這一點之外,和原生的事件并無差別

二、在React中事件處理函數(shù)主要的三中寫法,不同的寫法解決this指向問題的方式也不同,性能也有差異,具體如下:
1. 使用es6的箭頭函數(shù)
 class MyComponent extends React.Component{
    constructor(){
        super(props);
        this.state = {
            number:0
        }
    }
    
    render(){
        <button onClick={(e)=>{console.log(this.state.number);}}>不服點我</button>
    }
 }

分析,此時this指向的是函數(shù)定義時所在的對象,所以this總是指向當(dāng)前組件的實例,不足是當(dāng)前的組件邏輯比較復(fù)雜時,把組件的邏輯寫在{}內(nèi)會導(dǎo)致render的臃腫,不容易比較直觀的看出UI的結(jié)構(gòu),同時代碼的可讀性也不會很好,解決方法為把邏輯封裝為組件的一個方法,然后在函數(shù)中調(diào)用這個方法:

    class MyComponent extends React.Component{
    constructor(){
        super(props);
        this.state = {
            number:0
        }
    }
    handleClick(e){
        const number = ++this.state.number;
        this.setState({
            number
        });
    };
    
    render(){
        <button onClick={(e)=>this.handleClick(e);}>不服點我</button>
    }

注意,直接在render中定義事件處理函數(shù)的最大的問題就是,每次render調(diào)用的時候都會創(chuàng)建一個新的事件處理函數(shù),給組件帶來額外的開銷,當(dāng)組件的層級越低,開銷就越大,組件上的任何上一層級組件的變化都會觸發(fā)這個組件的render方法(一般可以忽略)。

2.使用組件的方法

直接將組件的方法賦值給這個事件的元素,同時在構(gòu)造函數(shù)中將這個方法的this綁定到當(dāng)前對象,如:

   class MyComponent extends React.Component{
    constructor(){
        super(props);
        this.state = {
            number:0
        }
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick(e){
        const number = ++this.state.number;
        this.setState({
            number
        });
    };
    
    render(){
        <button on click={this.handleClick}>不服點我</button>                   
    }

這種方法的好處是每次渲染都不會重新創(chuàng)建一個回調(diào)函數(shù),沒有額外的性能損失;
但是,如果在一個組件中有很多的事件函數(shù)時,這種在構(gòu)造函數(shù)中綁定this的方法就會比較繁瑣,所以還可以直接在給事件屬性直接賦值時綁定this;

    class MyComponent extends React.Component{
        constructor(){
            super(props);
            this.state = {
                number: 0
            }
        }
        
        handleClick(e){
            const number = ++this.state.number;
            this.setState({
                number
            });
        }
        
        render(){
            <div>{this.state.number}</div>
            <button onClick={this.handleClick.bind(this)}>點我</button>
        }
    }

分析:
(1)缺點: 此方法在每次render時都會重新創(chuàng)建一個函數(shù),在性能上有所損失;
(2)優(yōu)點: 事件處理函數(shù)需要傳參數(shù)時,這個方法比較好,看下面的例子

    class MyComponent extends React.Component{
        constructor(){
            super(props);
            this.state = {
                list: [1, 2, 3, 4, 5],
                current: 1
            }
        }
        
        //每點擊一項,將點擊項設(shè)置為當(dāng)前項,所以需要將點擊項作為參數(shù)傳遞
        handleClick(item, e){
            this.setState({
                current: item
            });
        }
        
        render(){
            let { list } = this.state;
            return (
                <ul>
                {
                    (!!list && list.length>0) && list.map((listItem, index)=>{
                    return <li onClick={this.handleClick.bind(this, listItem)}>{listItem}</li>
                    })
                }
                </ul>
            )
        }
    
    
    }
3. 屬性初始化語法(property initializer syntax)

使用es7的屬性初始化語法會自動為class中的定義的方法綁定this,例如:

class MyComponent extends React.Component{
        constructor(){
            super(props);
            this.state = {
                number: 0
            }
        }
        
        handleClick = (e)=>{
            const number = ++this.state.number;
            this.setState({
                number
            });
        }
        
        render(){
            <div>{this.state.number}</div>
            <button onClick={this.handleClick}>點我</button>
        }
    }  

優(yōu)點:此種方法既不用擔(dān)心在構(gòu)造函數(shù)中綁定this,非常繁瑣;
也不用擔(dān)心在渲染時重復(fù)生成函數(shù),造成性能問題
這個還處在實驗性階段,默認(rèn)不支持,但是官方的腳手架 creat-react-app 默認(rèn)支持;如果你要是想在項目中使用,你可以在項目中引入babel 的 transform-class-properties 插件獲取這個特性的支持。

以上為react事件處理的三種方式以及this問題的全部內(nèi)容,如有不當(dāng),歡迎指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容