2015-11-28 64 views
51
class PlayerControls extends React.Component { 
    constructor(props) { 
    super(props) 

    this.state = { 
     loopActive: false, 
     shuffleActive: false, 
    } 
    } 

    render() { 
    var shuffleClassName = this.state.toggleActive ? "player-control-icon active" : "player-control-icon" 

    return (
     <div className="player-controls"> 
     <FontAwesome 
      className="player-control-icon" 
      name='refresh' 
      onClick={this.onToggleLoop} 
      spin={this.state.loopActive} 
     /> 
     <FontAwesome 
      className={shuffleClassName} 
      name='random' 
      onClick={this.onToggleShuffle} 
     /> 
     </div> 
    ); 
    } 

    onToggleLoop(event) { 
    // "this is undefined??" <--- here 
    this.setState({loopActive: !this.state.loopActive}) 
    this.props.onToggleLoop() 
    } 

我要更新切換loopActive狀態裏面,但this對象是在處理不確定的。根據教程文檔,I this應該引用該組件。我錯過了什麼嗎?陣營:「這個」沒有定義的組件功能

回答

72

ES6 React.Component不會自動將方法綁定到自身。你需要在構造函數中自己綁定它們。就像這樣:

constructor (props){ 
    super(props); 

    this.state = { 
     loopActive: false, 
     shuffleActive: false, 
    }; 

    this.onToggleLoop = this.onToggLoop.bind(this); 

} 
+4

如果您將onClick屬性更改爲'()=> this.onToggleLoop',然後將onToggleLoop函數移動到您的反應類中,它也會起作用。 – Sam

+18

你真的必須綁定每個反應類的每個方法嗎?這不是有點瘋狂嗎? –

+2

@AlexL有許多方法可以在不顯式綁定方法的情況下完成。如果你使用babel,可以將React組件的每個方法聲明爲箭頭函數。這裏有一些例子:https://babeljs.io/blog/2015/06/07/react-on-es6-plus – Ivan

37

有幾種方法。

一種是在構造函數中添加 this.onToggleLoop = this.onToggleLoop.bind(this);

另一個是箭頭函數 onToggleLoop = (event) => {...}

然後有onClick={this.onToggleLoop.bind(this)}

+0

@limelights感謝編輯。 –

+0

不錯,很清楚。 – Ionut

+0

爲什麼onToogleLoop =()=> {}工作? 我得到了同樣的問題,我bindet在我的構造函數,但它沒有工作......現在我已經看到你的帖子,並用箭頭函數語法替換我的方法,它的工作原理。你能解釋給我嗎? – DrMed

7

我遇到了一個類似的綁定在渲染功能,並最終傳遞的this情況下以下列方式:

{someList.map(function(listItem) { 
    // your code 
}, this)} 

我以前也用過:

{someList.map((listItem, index) => 
    <div onClick={this.someFunction.bind(this, listItem)} /> 
)} 
+0

這是您在此處創建的大量不必要的函數,每次都是這樣該列表呈現... –

+0

@TJCrowder是的,這是真的,每次調用渲染時都會重新創建這些函數。最好將函數創建爲類方法,並將它們綁定到類,但對於初學者,手動上下文綁定可能會有幫助 – duhaime

0

如果您在生命週期方法(如componentDidMount)中調用您創建的方法 ...那麼您只能使用this.onToggleLoop = this.onToogleLoop.bind(this)和胖箭頭功能onToggleLoop = (event) => {...}

在構造函數中聲明一個函數的常規方法不會工作,因爲生命週期方法在前面調用。

4

寫你的函數是這樣的:

onToggleLoop = (event) => { 
    this.setState({loopActive: !this.state.loopActive}) 
    this.props.onToggleLoop() 
} 

http://www.react.express/fat_arrow_functions

的關鍵字的結合,這是相同的外部和脂肪箭頭函數內。這與使用函數聲明的函數不同,後者可以在調用時將其綁定到另一個對象。維護這個綁定對於映射等操作非常方便:this.items.map(x => this.doSomethingWith(x))。

-1

它有些常見的調試程序設置斷點時,使用上述戰略,以正確綁定它仍然會返回undefined,即使錯過this作用域。

有時它會在重新編譯後正確綁定。也就是說,關閉webpack服務器並重新編譯,不要只是熱重新編譯。

假陰性並不總是意味着你的代碼被破壞。