React.js中setInterval内的访问状态问题

Issue accessing state inside setInterval in React.js

本文关键字:访问 状态 问题 js setInterval React      更新时间:2023-09-26

我正试图以这种方式访问setInterval内部组件的状态,但它不起作用:

componentDidMount: function() {
    setInterval(function() {
      console.log(this.state);
    }, 3000);
}

然而,如果我把回调函数放在一个单独的组件方法中,它可以完美地工作:

displayState: function() {
  console.log(this.state)
}
componentDidMount: function() {
    setInterval(this.displayState(), 3000);
}

知道为什么会发生这种事吗?我更愿意使用第一个选项。

在第一个示例中,当回调函数触发时,this超出了作用域。解决这个问题的一种方法是使用一个变量:

componentDidMount: function() {
    var self = this;
    setInterval(function() {
      console.log(self.state);
    }, 3000);
}

第二次尝试的问题是,您正在立即调用该函数,并将执行该函数的结果传递给setInterval。您应该传递函数本身,注意绑定this:的值

componentDidMount: function() {
    setInterval(this.displayState.bind(this), 3000);
}

为了澄清,此方法与您问题中的第二个示例之间的区别在于,这里将函数传递给setInterval(因为function.bind()返回函数)。

由于您使用的是React.createClass,因此由于自动绑定,不需要自己管理this的绑定。这意味着您只需传递函数本身,this将与原始上下文中的相同:

componentDidMount: function() {
    setInterval(this.displayState, 3000);
}

当然,最合适的方法取决于您是否喜欢使用匿名函数。

您需要使用对this的正确引用来执行间隔处理程序。使用React的自动绑定作为最清晰的解决方案IMO:

displayState: function() {
  console.log(this.state)
},
componentDidMount: function() {
    setInterval(this.displayState, 3000)
}

或者,如果您想要匿名函数,请使用bind

componentDidMount: function() {
    setInterval(function() {
        console.log(this.state)
    }.bind(this), 3000)
}

对于函数语法,这应该完成访问区间函数内的道具和状态的技巧:

useEffect(() => {
    //run instantly
    functionThatShouldRunEveryTenSeconds(props);
    const interval = setInterval(() => {
        //every 10 seconds
        functionThatShouldRunEveryTenSeconds(props);
    }, 1000);
    return () => clearInterval(interval);
}, []);

您应该能够正常访问状态和道具等所有内容。