2015-11-28 36 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服务器并重新编译,不要只是热重新编译。

假阴性并不总是意味着你的代码被破坏。