记住这段代码:
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()
,这也无效。这有什么灯吗?谢谢!
答案 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(this.setState.bind(this, {position:1}), 3000);
使用 function.prototype.bind()
setTimeout获取函数的位置并将其保留在上下文中。
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
和 setInterval
实际上接受可选的无限参数。
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.
要修复它,您有三个选择。
setTimeout(this.doSomething, 500)
this
透明的匿名箭头函数中,this
。setTimeout(() => this.doSomething(), 500)
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
);