在React

时间:2018-11-02 14:52:57

标签: javascript reactjs

我有一个使用setInterval的React组件。我希望能够在setInterval内使用组件的this,但是this成为setInterval内的窗口,然后this成为回调中的undefined

这两个都是箭头功能,所以这对我来说是意外的,但是到那时我可能还不了解内部工作。

这里是例子:

class MyComponent extends React.Component {
  constructor(){
    super()
    this.hasEndedTimer = this.hasEndedTimer.bind(this)
    ...
    this.hasEndedTimer(()=>{
      // the callback 'this' is now undefined? Even though an arrow 
      function?    
    })      
  }
...
  hasEndedTimer(callback) {
    const intervalId = setInterval(() => {
      // 'this' is now the window instead of the component? Even though arrow
      if(somecondition()) callback()
    }, 1000)
  }

...
}

我可以在this内维护react组件的setInterval上下文吗?

注意:如果将setInterval中的箭头函数更改为绑定了this的匿名函数,则this上下文仍然是该组件。

  hasEndedTimer(callback) {
    const intervalId = setInterval((function() {
      // 'this' is now the component. Works as expected.
      if(somecondition()) callback()
    }).bind(this), 1000)
  }

1 个答案:

答案 0 :(得分:1)

希望这会对您有所帮助。

构造函数必须具有super()。

react Component文档没有此表达式对象。它必须从父组件中获取此表达式对象。因此必须使用super()来获取此对象。

并且您需要在构造函数中绑定hasEndedTimer。

如果忘记绑定this.handleClick并传递它,则在实际调用该函数时将无法定义。

this.hasEndedTimer = this.hasEndedTimer.bind(this)

如果使用箭头功能,则无需绑定(此)。

在setInterval中,这是不同的。

“ This”通常指向window或global。当需要指向类实例时,应使用bind将其绑定到回调。像这样

declare (){
  console.log(...);
};
setInterval(this.declare.bind(this), 1000);

因此,您在setInterval中设置的函数实际上是一个回调函数,可以将此指向类实例。因此“ this”效果很好。

关于箭头功能。

箭头函数本身没有它,它必须从作用域链的上部继承。并且不需要使用bind。定义“ this.hasEndedTime”箭头函数的方式有问题。

this.hasEndedTimer = ()=>{
   ...  
}
//how to use it 
this.hasEndedTimer()

并且箭头功能中的setInterval应该注意函数内部的“ this”。

内部函数“ this”是固定的,指向未使用的定义范围。这里是一个示例。

function Timer() {
  this.s1 = 0;
  setInterval(() => this.s1++, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);