javascript-ReactJS:setTimeout()不起作用?

请记住以下代码:

var Component = React.createClass({

    getInitialState: function () {
        return {position: 0};    
    },

    componentDidMount: function () {
        setTimeout(this.setState({position: 1}), 3000);
    },

    render: function () {
         return (
            <div className="component">
                {this.state.position}
            </div>
         ); 
    }

});

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);

难道不应该在3秒后改变状态吗? 它立即改变。

我的主要目标是每3秒更改一次状态(使用setInterval()),但是由于它不起作用,我尝试了setTimeout(),该方法也不起作用。 上面有灯吗? 谢谢!

jbarradas asked 2019-10-09T16:09:20Z
9个解决方案
153 votes

setTimeout(
    function() {
        this.setState({position: 1});
    }
    .bind(this),
    3000
);

否则,您会将setState的结果传递给setTimeout

Daniel A. White answered 2019-10-09T16:09:37Z
112 votes
setTimeout(() => {
  this.setState({ position: 1 });
}, 3000);

由于ES6箭头功能不会更改this的上下文,因此上述方法也将起作用。

Steven Scaffidi answered 2019-10-09T16:10:07Z
16 votes

每当我们创建超时时,我们都应该在componentWillUnmount上清除它(如果尚未触发)。

      let myVar;
         const Component = React.createClass({

            getInitialState: function () {
                return {position: 0};    
            },

            componentDidMount: function () {
                 myVar = setTimeout(()=> this.setState({position: 1}), 3000)
            },

            componentWillUnmount: () => {
              clearTimeout(myVar);
             };
            render: function () {
                 return (
                    <div className="component">
                        {this.state.position}
                    </div>
                 ); 
            }

        });

ReactDOM.render(
    <Component />,
    document.getElementById('main')
);
Khalid Azam answered 2019-10-09T16:10:35Z
6 votes

由于括号,正在立即调用setState! 将其包装在一个匿名函数中,然后调用它:

setTimeout(function() {
    this.setState({position: 1})
}.bind(this), 3000);
tymeJV answered 2019-10-09T16:11:02Z
6 votes

我知道这有点旧,但是要注意,React建议重新安装组件,以清除安装间隔:[https://reactjs.org/docs/state-and-lifecycle.html]

所以我想在这个讨论中添加这个答案:

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
Fernando Lopes answered 2019-10-09T16:11:39Z
4 votes

您的代码范围(window)将是您的window对象,而不是您的react组件,这就是为什么setTimeout(this.setState({position: 1}), 3000)将以这种方式崩溃的原因。

那来自javascript而不是React,它是js闭包


因此,为了绑定当前的反应组件范围,请执行以下操作:

setTimeout(function(){this.setState({position: 1})}.bind(this), 3000);

或者,如果您的浏览器支持es6或您的projs支持将es6编译为es5,请尝试使用箭头功能,因为箭头功能可以解决“此”问题:

setTimeout(()=>this.setState({position: 1}), 3000);
Xin answered 2019-10-09T16:12:28Z
2 votes

有3种方法可以访问“ setTimeout”函数内部的范围

第一,

const self = this
setTimeout(function() {
  self.setState({position:1})
}, 3000)

其次是使用ES6箭头功能,导致箭头功能没有自身作用域(此)

setTimeout(()=> {
   this.setState({position:1})
}, 3000)

第三是绑定函数内部的范围

setTimeout(function(){
   this.setState({position:1})
}.bind(this), 3000)
Darryl Fabian answered 2019-10-09T16:13:14Z
2 votes

你没有告诉谁叫setTimeout

在这里,如何调用超时而无需调用其他功能。

1.您可以执行此操作而无需执行其他功能。

setTimeout(this.setState.bind(this, {position:1}), 3000);

使用function.prototype.bind()

setTimeout获取函数的位置并将其保留在上下文中。

2.即使编写更少的代码,也可以做到这一点。

setTimeout(this.setState, 3000, {position:1});

可能在某些时候使用了相同的绑定方法

setTimeout仅占据函数的位置,并且函数已经具有上下文? 无论如何,它有效!

注意:这些可与您在js中使用的任何功能一起使用。

Advis answered 2019-10-09T16:14:43Z
0 votes

您做了语法声明错误,请使用正确的setTimeout声明

message:() => { 
  setTimeout(() => {this.setState({opened:false})},3000); 
  return 'Thanks for your time, have a nice day 😊! 
}
KARTHIKEYAN.A answered 2019-10-09T16:15:15Z
translate from https://stackoverflow.com:/questions/36270422/reactjs-settimeout-not-working