You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mobx无法识别setInterval内的store状态更新问题

问题原因

核心问题是UserStore中的pingResult没有被标记为MobX可观察(Observable)状态。
MobX 6+ 版本默认不会自动将类的普通属性转为响应式状态,如果你没有在类构造函数中调用makeAutoObservable或makeObservable做响应式初始化,哪怕你在runInAction里修改属性值,MobX也不会追踪这个属性的变更,自然无法通知包裹了observer的组件重渲染——这和你赋值时是不是用深拷贝生成新对象没有关系。
另外有几个容易忽略的细节也会导致同类现象:

  • useRootStore每次执行都创建新的store实例,导致组件渲染时拿到的store和定时器里调用的store不是同一个引用
  • observer高阶组件导错来源,没有使用mobx-react-lite/mobx-react导出的observer方法
  • 你贴的ScreenA代码里存在拼写错误:retunr应为return,这类语法错误也会干扰组件正常的渲染逻辑
  • useEffect没有传对依赖、组件卸载时未清理定时器,也可能引发状态引用异常
修复方案
  1. 给UserStore添加响应式初始化,修改后的Store代码如下:
import { makeAutoObservable, runInAction } from "mobx";

class UserStore {
  pingResult = null;

  constructor(userService) {
    // 自动将类属性标记为observable,普通方法标记为action
    makeAutoObservable(this);
    this.userService = userService;
  }

  ping = async () => {
    console.log('ping');
    const pingResult = await this.userService.ping();
    runInAction(() => {
      this.pingResult = pingResult;
    });
  };
}
  1. 检查useRootStore实现,确保全局只初始化一次store实例,不要在hook每次执行时重复new UserStore。
  2. 修正组件里的拼写错误,确认observer导入来源正确,补充定时器清理逻辑:
import { observer } from "mobx-react-lite"; // 纯函数组件场景用这个包即可

const ScreenA = observer(() => {
  const { userStore } = useRootStore();

  useEffect(() => {
    const timer = setInterval(() => {
      userStore.ping();
    }, 3000);
    // 组件卸载时清理定时器,避免内存泄漏
    return () => clearInterval(timer);
  }, [userStore]);

  console.log(userStore.pingResult);

  return <></>
});

补充:如果你还在使用MobX 5及更早版本,需要通过@observable装饰器标记pingResult属性,才能让状态变更被组件追踪到。

修改完成后,每3秒ping接口更新值时,组件内的日志会正常打印最新的pingResult,重渲染行为符合预期。

内容的提问来源于stack exchange,提问作者Oleg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:27:25