为什么react中的setTimeout会取到旧值
·
示例代码及原因
下面class和hooks的写法里,setTimeout 取到的都是旧值,是因为 react 中一直遵循一个原则,即 state 指向的内容是不可变的,所以每一次 state 的更新都是指向变了。注意,这里是state指向变了,并不是释放,只有原来指向的对象没有其它引用的时候,才会被释放
因为闭包的原因,setTimeout中依然指向的原来的对象,所以旧的state没有释放,所以会取到旧值。
在
react中,组件的每一次 渲染都是那一瞬间的状态
import React, { useState } from "react";
// hooks 示例
function Example2() {
const [count, setCount] = useState(0);
function handleAlertClick() {
setTimeout(() => {
alert("You clicked on: " + count);
}, 3000);
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
// class 示例
class Example extends React.Component {
state = {
count: 0
};
setCount = count => {
this.setState(count);
};
handleAlertClick = () => {
setTimeout(() => {
alert("You clicked on: " + this.state.count);
}, 3000);
};
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setCount(this.state.count + 1)}>
Click me
</button>
<button onClick={this.handleAlertClick}>Show alert</button>
</div>
);
}
}
export default Example;
解决办法
使用 ref
function Example() {
const [count, setCount] = useState(0);
let ref = useRef();
ref.current = count;
function handleAlertClick() {
setTimeout(() => {
alert("You clicked on: " + ref.current);
}, 3000);
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
更多推荐
所有评论(0)