ReactJS:setTimeout()不起作用?

时间:2016-03-28 20:17:19

标签: javascript reactjs

记住这段代码:

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(),这也无效。这有什么灯吗?谢谢!

11 个答案:

答案 0 :(得分:162)

待办事项

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

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

答案 1 :(得分:114)

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

上述方法也有效,因为ES6箭头功能不会改变this的上下文。

答案 2 :(得分:17)

无论何时我们创建超时,我们都应该在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')
);

答案 3 :(得分:6)

由于括号,

setState被立即调用!将它包装在一个匿名函数中,然后调用它:

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

答案 4 :(得分:6)

我知道这有点旧了,但是请务必注意,React建议重新安装组件以卸载间隔:https://reactjs.org/docs/state-and-lifecycle.html

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

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

答案 5 :(得分:4)

您的代码范围(this将是您的window对象,而不是您的反应组件,这就是setTimeout(this.setState({position: 1}), 3000)将以这种方式崩溃的原因。< / p>

来自javascript而不是React,它是 js closure

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

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

或者如果您的浏览器支持es6或您的projs支持将es6编译为es5,请尝试使用箭头功能,因为arrow func是修复'this'问题:

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

答案 6 :(得分:4)

您没有告诉谁叫setTimeout

在这里,您无需调用其他功能即可调用超时。

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

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

使用 function.prototype.bind()

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

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

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

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

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

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

答案 7 :(得分: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)

答案 8 :(得分:2)

只需将函数作为引用传递即可,无需将其包装在匿名函数中甚至绑定它,从而创建另一个函数。

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

输入 setTimeout

人们似乎没有意识到 setTimeoutsetInterval 实际上接受可选的无限参数

setTimeout(callback, timeout?, param1?, param2?, ...)

原因是为了让调用回调更简单,所以代替这个

setTimeout(
  function(){
    this.doSomething(true, "string", someVariable)
  }.bind(this),
  500
)

你可以写这个

setTimeout(this.doSomething, 500, true, "string", someVariable)

是不是很漂亮很优雅? ?


错误?

React 立即调用 setTimeout 没有错误,所以如果你对此感到困惑,请考虑这个。

function doSomething() {/* */}

const a = doSomething() // immediately invokes and assigns a result
const b = doSomething   // stores a reference for later call

// call later
const x = a() // error
const y = b() // invokes doSomething and assigns a result

在您使用 setState 的情况下,这基本上是一样的。
当您注册 setTimeout 回调时,您错误地立即调用了它,而您应该传递对它的引用。

function doSomething() {/* */}

// wrong
setTimeout(doSomething(), 500) // This is basically the same as writing the `a` from above
setTimeout(a, 500)             // like this. See the problem? a() cannot be called later.

要修复它,您有三个选择。

  1. 传递引用
setTimeout(this.doSomething, 500)
  1. 包裹在对this透明的匿名箭头函数中,
    意味着它捕获外部(父)this
    请注意,每次调用此函数时,它都会将您的函数包装在另一个函数中
setTimeout(() => this.doSomething(), 500)
  1. 包装在一个标准的匿名函数中,但由于它带有自己的 this,您必须将其绑定到父函数的 this
    注意,这将你的函数包装在另一个函数中,然后绑定它,每次都会创建第三个函数
setTimeout(function(){this.doSomething()}.bind(this), 500)

答案 9 :(得分:0)

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

message:() => { 
  setTimeout(() => {this.setState({opened:false})},3000); 
  return 'Thanks for your time, have a nice day ! 
}

答案 10 :(得分:0)

尝试使用设置超时的ES6语法。普通的javascript setTimeout()在react js中不起作用

setTimeout(
      () => this.setState({ position: 100 }), 
      5000
    );