【问题标题】:Weird class property behaviour奇怪的类属性行为
【发布时间】:2017-04-10 17:21:03
【问题描述】:

我正在使用 React,但遇到了一些奇怪的事情。

class C extends React.Component {

    componentDidMount = this.animate; // <---

    animate = () => ...

}

这不起作用,所以我不得不更改 componentDidMount 的值并且它起作用了:

class C extends React.Component {

    componentDidMount = () => this.animate(); // Lambda is required?

    animate = () => ...

}

有人对为什么需要这样做有很好的解释吗?

【问题讨论】:

  • 可能animate 内部使用this,当通过this.animate() 调用时与通过对animate 的函数引用时会有所不同。而是尝试:componentDidMount = this.animate.bind(this) 绑定thisArg
  • 我认为这不是问题,因为第二个代码 sn-p 运行良好
  • 这表明调用实际上是问题所在,所以我的建议应该有效。显示this.animate函数的内容
  • 我展示的只是一个例子。我想知道的是为什么这两个代码 sn-ps 不等价
  • 请注意,类属性不是 ES6 的一部分。

标签: javascript reactjs ecmascript-6 ecmascript-next


【解决方案1】:

如果你写

class C extends React.Component {
   componentDidMount = this.animate; // <---
   animate = () => ...
}

然后将componentDidMount 设置为undefined,因为当时没有设置animate

对于componentDidMount = () =&gt; this.animate();,每次调用componentDidMount 时都会解析this.animate();,这就是为什么这对你有用。

如果你这样写:

class C extends React.Component {
   animate = () => ...
   componentDidMount = this.animate; // <---
}

然后componentDidMount 将引用您之前分配给animate 的函数。

但是如果你想为一个类定义方法,你应该检查baao的答案,因为那样你不应该使用赋值,而是使用方法定义animate() {}

【讨论】:

  • 这个语法是什么? animatecomponentDidMount 应该是该组件的实例属性吗?你不应该把它写成animate() { /* ... */ }animate: function () { /* ... */ } 等吗?这些看起来像全局变量
  • @WilliamB 分配是在构建阶段评估的,所以是的,它们是实例属性。如果你写animate() { /* ... */ }那么它是一个类的方法,它会在构造阶段之前设置到原型链,所以OP肯定也可以通过使用animate() { /* ... */ }来解决这个问题,这确实是一个更好的主意.
  • 方法是首选方法吗?原因是它们是在施工前设置的吗?还有其他原因吗?
  • @justasking 老实说,我现在不能告诉你标准是如何准确定义它的,但是如果你使用像 babeljs 这样的编译器,那么使用animate = () =&gt; ... 语法,() =&gt; ... 的新实例将为类的每个实例创建(所以这会有一点开销)。使用animate() {},所有实例都将共享相同的功能。一般来说,您应该始终使用animate() {}。我目前没有想到animate = () =&gt; ... 可能有用的情况。
  • @justasking 在对另一个问题FelixKling 的评论中提到了一个用例。对于箭头函数,this 绑定到创建它们的this(在本例中为类的实例)。因此,如果您将函数用作回调,这可能会很有用,因为您不需要手动将它们绑定到类的实例。
【解决方案2】:

您应该将 animate 方法定义为类方法,而不是箭头函数。

class C extends React.Component {
    componentDidMount = this.animate;
    animate() {}
}

【讨论】:

  • 那要看方法怎么用了。
  • OPs 用法表明他认为使用类方法,不是吗? @FelixKling
  • 如果它没有在其他任何地方使用(例如,作为render 中的事件处理程序),那么可以。这就是我所说的“依赖”。
  • @baao 问题不在于我是否应该使用方法。以不同的方式提出的问题是:为什么第二个代码 sn-p 有效,而不是第一个?我认为 t.niese 很好地解释了这一点。
  • @justasking 你的问题标题是关于“奇怪的类属性行为”,但你没有定义类属性,而是一个恰好在类中的函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多