React useState异步代码没有更新?
背景:
React代码如下
import { useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
setTimeout(() => {
console.log(count, 'end'); // 还是 0!
}, 5000);
}
return (
<>
<button onClick={handleClick}>+1</button>
<span>{count}</span>
</>
);
}
setCount的更新是异步更新的,setTimeout也是异步的,为什么点击,console.log打印的是0,而不是1。
尝试:
尝试用普通js函数进行比较,js代码如下
function outerFunction() {
let count = 0;
function innerFunction() {
console.log(count);
}
count = 1; // 将count更新为1
setTimeout(innerFunction, 5000);
count = 2;
}
outerFunction();
console.log打印的是最新的值2。
疑问: 两段代码的打印结果不同,是什么原因呢?
回复
1个回答

test
2024-06-20
setTimeout(() => {
console.log(count, 'end'); // 还是 0!
}, 5000);
你可以把react
组件的每次渲染理解为生成了一个平行宇宙。
初始化渲染时生成的平宇宙,其count
值为0
,所以就算定时器延迟一年执行,它也只能输出0
。
当你调用setCount(count + 1)
,这触发了第二次渲染,又生成了一个平行宇宙,这个平行宇宙中的count
是1
,这个宇宙中的定时器也就只能输出1
。
去掉定时器帮助理解
const handleClick = () => {
setCount(count + 1);
console.log(count, 'end');
}
// 两者其实是一样的,加上定时器并不会让count拥有穿透平行宇宙的能力
const handleClick = () => {
setCount(count + 1);
setTimeout(() => {
console.log(count, 'end');
}, 5000);
}
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容