React:在组件函数中未定义"this"

Max*_*s S 121 this reactjs

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()
  }
Run Code Online (Sandbox Code Playgroud)

我想loopActive在切换时更新状态,但是this在处理程序中未定义对象.根据教程文档,我this应该参考该组件.我错过了什么吗?

Iva*_*van 181

ES6 React.Component不会自动将方法绑定到自身.您需要在构造函数中自己绑定它们.像这样:

constructor (props){
  super(props);

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

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

}
Run Code Online (Sandbox Code Playgroud)

  • 你真的必须绑定每个反应类的每个方法吗?这不是有点疯狂吗? (64认同)
  • 如果在将onToggleLoop函数移动到您的react类之后将onClick属性更改为`()=> this.onToggleLoop`,它也将起作用. (17认同)
  • @AlexL有一些方法可以在不明确绑定方法的情况下完成.如果您使用babel,则可以将React组件上的每个方法声明为箭头函数.这里有一些例子:https://babeljs.io/blog/2015/06/07/react-on-es6-plus (6认同)
  • 但是为什么"这个"首先是未定义的?我知道Javascript中的`this`取决于函数的调用方式,但是这里发生了什么? (6认同)
  • 本文的 TLDR:请改用箭头函数。 (4认同)
  • @Ivan,这篇文章实际上位于:https://babeljs.io/blog/2015/07/07/react-on-es6-plus,感谢您提供的信息,这正是我正在寻找的!:D (2认同)
  • 我发现我必须将“onClick”属性绑定到 @Sam 略有不同。在所示的示例中,它将是 `onClick={ () =&gt; { this.onToggleLoop(); }}` - 总的来说,我和“这不是有点疯狂”的人群在一起吗? (2认同)

J. *_*ens 79

有几种方法.

一种是this.onToggleLoop = this.onToggleLoop.bind(this);在构造函数中添加 .

另一个是箭头功能 onToggleLoop = (event) => {...}.

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

  • 来自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions; 箭头函数不会创建自己的this,使用封闭执行上下文的this值. (5认同)
  • 为什么 onToogleLoop = () =&gt; {} 有效?我遇到了同样的问题,我在我的构造函数中绑定了它,但它没有用……现在我看到了你的帖子,并用箭头函数语法替换了我的方法,它可以工作。你能给我解释一下吗? (3认同)
  • 请注意,“onClick”中的内联绑定将在每次渲染时返回一个新函数,因此看起来好像已为 prop 传递了一个新值,与“PureComponent”中的“shouldComponentUpdate”混淆。 (3认同)

小智 19

用这种方式写你的函数:

onToggleLoop = (event) => {
    this.setState({loopActive: !this.state.loopActive})
    this.props.onToggleLoop()
}
Run Code Online (Sandbox Code Playgroud)

http://www.react.express/fat_arrow_functions

关键字的绑定在胖箭头函数的外部和内部是相同的.这与使用function声明的函数不同,函数可以在调用时将其绑定到另一个对象.维护此绑定对于映射操作非常方便:this.items.map(x => this.doSomethingWith(x)).

  • 太糟糕了,你不能在 React 中使用正常的类语法! (2认同)

duh*_*ime 11

我在渲染函数中遇到了类似的绑定,最终this以下列方式传递了上下文:

{someList.map(function(listItem) {
  // your code
}, this)}
Run Code Online (Sandbox Code Playgroud)

我也用过:

{someList.map((listItem, index) =>
    <div onClick={this.someFunction.bind(this, listItem)} />
)}
Run Code Online (Sandbox Code Playgroud)