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(),这也不工作。有灯光吗?谢谢!

357542 次浏览

由于括号的原因,setState被立即调用! 用一个匿名函数包装它,然后调用它:

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

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

否则,就是将 setState的结果传递给 setTimeout

您还可以使用 ES6箭头函数来避免使用 this关键字:

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

由于 ES6箭头函数不会更改 this的上下文,因此上述方法也可以工作。

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

它来自 javascript 而不是 React,它是 JS 结束


因此,为了绑定当前的 response 组件作用域,请执行以下操作:

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

或者如果您的浏览器支持 es6或者您的项目支持将 es6编译成 es5,也可以尝试使用 Arrow 函数,因为 Arrow func 可以解决“ this”问题:

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

任何时候我们创建一个超时,我们应该在组件 WillUnmount 上清除它,如果它还没有触发。

      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种方法可以访问“ 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)

你没有告诉谁打电话给 setTimeout

下面介绍如何在不调用其他函数的情况下调用超时。

1. 你可以在不增加额外函数的情况下做到这一点。

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

使用 < strong > function. Prototype.bind ()

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

2. 即使编写更少的代码,也可以做到同样的事情。

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

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

SetTimeout 只取函数的位置,而函数已经有了上下文!

注意: 这些函数适用于您在 js 中使用的任何函数。

我知道这有点老,但是重要的是要注意,React 建议在组件卸载时清除间隔: https://reactjs.org/docs/state-and-lifecycle.html

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

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

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

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

尝试使用 ES6的 set timeout 语法

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

只需将函数作为引用传递,不需要将它包装在匿名函数中,甚至不需要绑定它,这样就会创建另一个函数。

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 中没有 bug,所以如果您对此感到困惑,可以考虑这样做。

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 "a is not a function"
const y = b() // invokes doSomething and assigns a result

对于 setState来说,这基本上是一样的。
当您注册 setTimeout回调时,您错误地立即调用它,而应该在其中传递对它的引用。

function doSomething() {/* */}
const a = 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
    请注意,这会将函数封装在另一个函数中,然后 AND 绑定它,从而创建另一个函数。每次调用它都会增加两个函数。
setTimeout(function(){this.doSomething()}.bind(this), 500)
  useEffect(() => {
setTimeout(() => setActive(true), 5000);
    

},[]);