2016-02-29 40 views
0

今天我已經開始使用React構建,但是某些結果是某種意想不到的。所以我有些解釋會很好。我有以下組成部分:ReactJS直接訪問父函數onClick指向無限循環

var QuestionItem = React.createClass({ 
    sendVote: function(e) { 
     $(e.target).hasClass('up') 
      ? this.props.onVoteUpdate(this.props.id, 'up') 
      : this.props.onVoteUpdate(this.props.id, 'down'); 
    }, 


    render: function() { 
     return (
      <li data-up={this.props.up} data-down={this.props.down}> 
       <div className="votes"> 
        <span className="up" onClick={this.sendVote}>+</span> 
        <span className="down" onClick={this.sendVote}>-</span> 
       </div> 
      </li> 
     ); 
    } 
}); 

當我在跨度點擊我要觸發我的父組件的onVoteUpdate功能,但爲什麼有必要創建一個名爲額外功能(對我來說)sendVote

由於如下所示,當我直接執行功能onClick

<div className="votes"> 
    <span onClick={this.props.onVoteUpdate(this.props.id, 'up')}>+</span> 
    <span onClick={this.props.onVoteUpdate(this.props.id, 'down')}>-</span> 
</div> 

它在控制檯日誌的無限循環結束。

onVoteUpdate: function(question, state) { 
    console.log(question); 
    console.log(state); 
}); 

這是不可能的,還是我做錯了什麼?

回答

0

你總是需要記住的一件事:JSX是不是 HTML

這可能有助於看到JSX如何編譯:

<div className="votes"> 
    <span onClick={this.props.onVoteUpdate(this.props.id, 'up')}>+</span> 
    <span onClick={this.props.onVoteUpdate(this.props.id, 'down')}>-</span> 
</div> 

編譯爲:

React.createElement('div', { className: 'votes' }, 
    React.createElement('div', { onClick: this.props.onVoteUpdate(this.props.id, 'up') }, '+'), 
    React.createElement('div', { onClick: this.props.onVoteUpdate(this.props.id, 'down') }, '-') 
) 

正如你所看到的,你不分配onClick處理程序到你的方法,你」實際上將它分配給該方法的返回值,因爲在渲染過程中實際調用了它。

我建議打破的行爲伸到兩種方法:

var QuestionItem = React.createClass({ 
    sendUpVote: function() { 
     this.props.onVoteUpdate(this.props.id, 'up'); 
    }, 

    sendDownVote: function() { 
     this.props.onVoteUpdate(this.props.id, 'down'); 
    }, 

    render: function() { 
     return (
      <li data-up={this.props.up} data-down={this.props.down}> 
       <div className="votes"> 
        <span className="up" onClick={this.sendUpVote}>+</span> 
        <span className="down" onClick={this.sendDownVote}>-</span> 
       </div> 
      </li> 
     ); 
    } 
}); 

即使它可能是一個多一點的代碼,讀什麼是應該發生的代碼時,它的更清楚。

2

昨天我真的花了很多時間在同一個問題。

當您將它分配給onClick事件時,您正在調用this.sendVote,這導致無限循環,因爲每次渲染時都會重新渲染,因爲狀態在this.sendVote等發生變化等等。

您寧願做的事情是將this.sendVote綁定到onClick事件。

這是你想要什麼:

<span className="up" onClick={this.sendVote.bind(this)}>+</span> 
<span className="down" onClick={this.sendVote.bind(this)}>-</span> 

這樣,你是不是叫this.sendVote,而不是你告訴「嘿每次我點擊這個<span>我想打電話給this.sendVote!」