useEffect 里怎么正确获取最新的 state 值?

程序猿新云 阅读 3

我在 useEffect 里想用最新的 count 值,但每次拿到的都是初始值 0,明明页面上已经显示更新后的数字了。是不是闭包的问题?我试过加依赖数组,也试过不加,都不行。

代码大概是这样的:

import { useState, useEffect } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => {
      console.log(count); // 这里总是输出 0
      setCount(c => c + 1);
    }, 1000);
    return () => clearInterval(timer);
  }, []); // 只在挂载时运行一次

  return <div>{count}</div>;
}

这到底该怎么解决啊?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
Mc.佳妮
Mc.佳妮 Lv1
确实是闭包问题。你写的空依赖数组导致 useEffect 只在挂载时执行一次,那个 setInterval 回调形成闭包,捕获的是创建时的 count 值(0),所以永远打印 0。

最直接的解决方案是用 useRef 存最新值:

import { useState, useEffect, useRef } from 'react';

function MyComponent() {
const [count, setCount] = useState(0);
const countRef = useRef(count);

// 每次 count 变化时更新 ref
useEffect(() => {
countRef.current = count;
}, [count]);

useEffect(() => {
const timer = setInterval(() => {
console.log(countRef.current); // 现在能拿到最新值了
setCount(c => c + 1);
}, 1000);
return () => clearInterval(timer);
}, []);

return
{count}
;
}


如果你只是想在 setCount 的时候用到当前值,函数式更新其实就能搞定,不需要 ref:

useEffect(() => {
const timer = setInterval(() => {
setCount(c => {
console.log(c); // 这里 c 就是最新的值
return c + 1;
});
}, 1000);
return () => clearInterval(timer);
}, []);


但如果你需要在回调里做其他操作(比如判断 count 是否大于某个值再决定下一步),那就得上 ref 了。

另外提醒一下,如果你在依赖数组里加 count,timer 会每次 count 变化时都重建,这个频率就太高了,不推荐。
点赞
2026-03-12 11:01