2015-11-05 70 views
2

我寫在反應的功能JSX其中包含需要跟this引用`this`在陣營JSX

this.socket.on('addWashedMission', washedMission => { 
     console.log('onAddWashedMission - %s - %s', washedMission.name, 
      new Date(washedMission.birthtime)); 

     this.state.washedMissions.filter(function(o) { 
      return o.name === washedMission.name; 
     }).forEach(function(element, i, arr) { 
      // HERE IT IS // 
      this.state.washedMissions.state.washedMissions.slice(
       this.state.washedMissions.state.washedMissions.indexOf(element), 1); 
     }); 

     this.state.washedMissions.push(washedMission); 
     this.state.washedMissions.sort(function(a,b) { 
      return b.birthtime - a.birthtime; 
     }); 

     this.setState({ 
      washedMissions: this.state.washedMissions 
     }); 
    }); 

通知的this.state.washedMissions回調?當我在回調中時,Firefox腳本調試器顯示瀏覽器不知道什麼是this,因此我無法以這種方式操縱我的數組。

如何確保this在我的回調範圍內 - 並且注意,回調是同步的,所以我不擔心任何計時問題。

+4

既然你已經在使用箭頭函數,爲什麼不用'forEach'呢? – Lucius

+0

李銀孔是對的。在forEach中使用箭頭功能並解決問題。 –

回答

2

使用更多的箭頭函數爲您所有的功能

this.socket.on('addWashedMission', washedMission => { 
    console.log('onAddWashedMission - %s - %s', washedMission.name, 
     new Date(washedMission.birthtime)); 

    this.state.washedMissions 
     .filter(o => { 
      return o.name === washedMission.name; 
     }) 
     .forEach((element, i, arr) => { 
      const elementIndex = this.state.washedMissions.state.washedMissions.indexOf(element); 
      this.state.washedMissions.state.washedMissions.slice(elementIndex, 1); 
     }); 

    this.state.washedMissions.push(washedMission); 
    this.state.washedMissions.sort((a,b) => { 
     return b.birthtime - a.birthtime; 
    }); 

    this.setState({ 
     washedMissions: this.state.washedMissions 
    }); 
}); 
1

問題是您的匿名函數範圍內的this未引用包含其定義的範圍。它將引用它所分配的對象的範圍,並在稍後調用它。

所以你需要「欺騙」它認爲this引用你想要的this

有幾種方法可以實現你想要的。

  1. 使用var that = this;定義您的匿名函數外,並與內,而不是this引用它來創建一個封閉。 (更好的向後兼容舊版本瀏覽器)

    var that = this; 
    this.state.washedMissions.filter(function(o) { 
        return o.name === washedMission.name; 
    }).forEach(function(element, i, arr) { 
        // HERE IT IS // 
        that.state.washedMissions.state.washedMissions.slice(
         that.state.washedMissions.state.washedMissions.indexOf(element), 1); 
    }); 
    
  2. 綁定您的匿名函數來定義它的範圍的this的傳遞到forEach方法(首選ECMA5方法處理這個)前的範圍

    this.state.washedMissions.filter(function(o) { 
        return o.name === washedMission.name; 
    }).forEach(function(element, i, arr) { 
        // HERE IT IS // 
        this.state.washedMissions.state.washedMissions.slice(
         this.state.washedMissions.state.washedMissions.indexOf(element), 1); 
    }.bind(this)); 
    
3

你有

...forEach(function(element, i, arr) { 
    this.state.washedMissions.state.washedMissions.slice(
    this.state.washedMissions.state.washedMissions.indexOf(element), 1); 
}); 

您需要提供thisArg作爲第二個參數Array.prototype.forEach

...forEach(function(element, i, arr) { 
    this.state.washedMissions.state.washedMissions.slice(
    this.state.washedMissions.state.washedMissions.indexOf(element), 1); 
}, this); // <--- note the `this` after the function() {} 

,或者您需要一個arrow function其詞法綁定this

...forEach((element, i, arr) => 
    this.state.washedMissions.state.washedMissions.slice(
    this.state.washedMissions.state.washedMissions.indexOf(element), 1) 
); 

或者您可以使用所提供的石器時代慢Function.prototype.bind在另一個答案

+0

其實我希望我接受這個答案,因爲你已經完成了所有3種方法! –