2016-01-23 145 views
1

我正嘗試使用React創建一個HTML列表。一切運作良好,但我得到一些奇怪的行爲與我分配給<li>標籤的點擊事件。這是兩個代碼,哪一個可以工作,但不是另一個。JavaScript React事件被奇怪地觸發

這兩個代碼之間的差異是我將onClick事件分配給<li> -tag的方式。

在沒有工作的代碼中,我告訴onMenuClick函數我在說的是area。當加載頁面時,我得到了這個方法三次。

在工作代碼中,我沒有提供任何有關onMenuClick函數的參數。雖然我無法知道哪個<li> -tag解僱了這個事件。我需要知道它,因爲我想對此作出反應。

爲什麼事件在不工作的代碼中發射三次?

不工作代碼:

var React = require('react'); 

var Application = React.createClass({ 
    onMenuClick: function(area) { 
    console.log('Application.onMenuClick(' + area + ')'); 
    }, 

    render: function() { 
    var classWideThis = this; 

    var areas = [ 
     { "id": 0, "name": "Bidirektional" }, 
     { "id": 1, "name": "Schleifen" }, 
     { "id": 2, "name": "Events" } 
    ]; 

    return (
     <div> 
     <h1>ReactJS Prototyp</h1> 
     <div className="menuWindow topAbstand"> 
      <ul className="menuUl"> 
      {areas.map(function(area) { 
       return <li className="menuLi" 
         key={area.id} 
         onClick={classWideThis.onMenuClick(area.name)}> 
         {area.name} 
        </li> 
      })} 
      </ul> 
     </div> 
     </div> 
    ); 
    } 
}); 

module.exports = Application; 

良好的工作代碼:

var React = require('react'); 

var Application = React.createClass({ 
    onMenuClick: function() { 
    console.log('Application.onMenuClick()'); 
    }, 

    render: function() { 
    var classWideThis = this; 

    var areas = [ 
     { "id": 0, "name": "Bidirektional" }, 
     { "id": 1, "name": "Schleifen" }, 
     { "id": 2, "name": "Events" } 
    ]; 

    return (
     <div> 
     <h1>ReactJS Prototyp</h1> 
     <div className="menuWindow topAbstand"> 
      <ul className="menuUl"> 
      {areas.map(function(area) { 
       return <li className="menuLi" 
         key={area.id} 
         onClick={classWideThis.onMenuClick}> 
         {area.name} 
        </li> 
      })} 
      </ul> 
     </div> 
     </div> 
    ); 
    } 
}); 

module.exports = Application; 

回答

2

onClick道具預期功能傳遞。您可以調用onMenuClick函數,並將其結果作爲第一個示例中的屬性傳遞。您可以更改onMenuClick函數返回函數處理單擊事件和使用封閉記住傳遞的參數:

onMenuClick: function(area) { 
    return function() { 
     console.log('Application.onMenuClick(' + area + ')'); 
    }; 
}, 

,然後把它傳遞給onClick

onClick={classWideThis.onMenuClick(area.name)} 

更先進的(但更好看)會到bind原始onMenuClick功能正確的上下文和預先參數:

onClick={classWideThis.onMenuClick.bind(classWideThis, aera.name)} 
+0

當我這樣做時,函數返回正確,但單擊時,我在瀏覽器的Web控制檯中獲得'Application.onMenuClick([object Object])'。似乎'area.name'沒有正確地傳送到'function(area)'的'area'參數中。你知道爲什麼? – Socrates

+0

嘗試調試一下。將對象打印到控制檯 - 「console.log(area)'。你能看見什麼? – madox2

+0

好吧,編輯完成後(將內部函數的'area'參數放到外部函數中),對於非綁定onClick,一切正常。 bind-onClick示例不起作用。 'onMenuClick.bind(...)'的優點是什麼? – Socrates