ReactJS:setTimeout()不起作用?

jba*_*das 79 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')
);
Run Code Online (Sandbox Code Playgroud)

是不是国家应该在3秒后改变?它正在迅速改变.

我的主要目标是每隔3秒(有setInterval())改变状态,但由于它不起作用,我试过setTimeout(),这也没有用.这有什么灯吗?谢谢!

Dan*_*ite 200

setTimeout(
    function() {
        this.setState({position: 1});
    }
    .bind(this),
    3000
);
Run Code Online (Sandbox Code Playgroud)

否则,您将结果传递setStatesetTimeout.

  • 对于那些喜欢使用ES6箭头功能的人:`setTimeout(()=> {this.setState({position:1})},3000)`@PositiveGuy不确定你是否自己研究了这个,因为这个问题被发布了,但是如果你还没有:Daniel的原始示例需要`.bind(this)`将`this`上下文限制为`setState` - 否则,`this`将自动引用它的上下文调用(在这种情况下,匿名`函数`被传递给`setTimeout`).但是,ES6箭头函数是_lexically scoped_ - 它们将`this`限制在它们被调用的上下文中. (9认同)

Ste*_*idi 134

setTimeout(() => {
  this.setState({ position: 1 });
}, 3000);
Run Code Online (Sandbox Code Playgroud)

以上也可以,因为ES6箭头功能不会改变上下文this.

  • ES6语法应该是React最佳实践的公认答案。两者都可以使用,但这更加优雅并且可以处理“ this”。 (2认同)

Kha*_*zam 22

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


Fer*_*pes 8

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

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

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
Run Code Online (Sandbox Code Playgroud)


tym*_*eJV 6

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

setTimeout(function() {
    this.setState({position: 1})
}.bind(this), 3000);
Run Code Online (Sandbox Code Playgroud)


Xin*_*Xin 5

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

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


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

setTimeout(function(){this.setState({position: 1})}.bind(this), 3000);
Run Code Online (Sandbox Code Playgroud)

或者,如果您的浏览器支持 es6 或者您的 projs 支持将 es6 编译为 es5,也可以尝试使用箭头函数,因为箭头函数是为了解决“这个”问题:

setTimeout(()=>this.setState({position: 1}), 3000);
Run Code Online (Sandbox Code Playgroud)


小智 5

你没有告诉谁叫setTimeout

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

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

setTimeout(this.setState.bind(this, {position:1}), 3000);
Run Code Online (Sandbox Code Playgroud)

使用function.prototype.bind()

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

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

setTimeout(this.setState, 3000, {position:1});
Run Code Online (Sandbox Code Playgroud)

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

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

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