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

MobX懒行为实现及代码问题:autorun不触发、useStrict规则疑问

嘿,我来帮你拆解这几个MobX的问题,一个个捋清楚:

问题1:怎么让延迟计算的_userArrayRev触发重新计算,让autorun生效

首先,MobX里的“懒行为/延迟计算”得靠computed来实现,它天生就是懒加载的——只有当被观察(比如在autorun里访问)时才会计算,而且依赖的可观察变量变化时会自动重新计算。你之前的_userArrayRev如果是普通变量,MobX根本不知道它和userArray的依赖关系,自然不会更新。

正确的做法是把_userArrayRev定义成computed属性:

// 假设你用类的写法
class Store {
  @observable userArray = [];

  // 用@computed标记这是一个计算属性
  @computed get userArrayRev() {
    console.log('重新计算反转数组');
    return this.userArray.slice().reverse();
  }
}

然后关键是在autorun的回调里必须访问这个computed属性,这样autorun才会建立和它的依赖关系:

autorun(() => {
  // 这里一定要用到userArrayRev,不然autorun根本不知道要追踪它
  console.log('反转后的列表:', store.userArrayRev);
});

这样每次userArray变化,userArrayRev会自动重新计算,autorun也会跟着触发。

问题2:为什么autorun预期执行3次,实际只跑了1次

结合上面的点,大概率是这几个原因:

  • autorun里没访问computed属性:如果你的autorun回调里根本没碰_userArrayRev,那它只会在初始化时执行一次,之后不管userArray怎么变都不会触发。
  • _userArrayRev不是computed变量:普通变量不会自动更新,依赖变化时它的值还是老的,autorun没理由重新执行。
  • 修改userArray的方式不对:如果你的userArray是observable数组,但你直接替换数组(比如this.userArray = [...this.userArray, '新用户'])而不用MobX提供的数组方法(push/splice/replace),MobX追踪不到变化,自然不会触发更新。

另外要注意:autorun默认会立即执行一次,如果你预期的3次是指调用3次AddUser对应的触发,那实际会是4次(初始化1次+3次更新)。如果想去掉初始化的那次,可以用reaction代替,它只在依赖变化时触发。

问题3:为什么开启useStrict(true)(enforceActions)后,AddUser()里能修改userArray

首先,新版MobX里useStrict(true)已经被configure({ enforceActions: "always" })替代了,但核心规则没变:只有在action函数内部才能修改可观察变量。

你能在AddUser()里修改成功,肯定是因为这个函数被MobX标记成action了:

  • 要么是用@action装饰器(比如@action AddUser() { ... })
  • 要么是用action()函数包裹(比如const AddUser = action(() => { ... }))

如果你的AddUser没被action装饰,开启严格模式后应该会直接报错,提示你不能在action外修改可观察变量。所以检查一下你的AddUser是不是被正确标记成action了。

最后给你一个完整的修正示例,你可以直接参考:

import { observable, computed, autorun, action, configure } from 'mobx';

// 启用严格模式,强制所有修改必须在action内
configure({ enforceActions: "always" });

class UserStore {
  @observable userArray = [];

  // 延迟计算的反转数组
  @computed get userArrayRev() {
    return this.userArray.slice().reverse();
  }

  // 标记为action,允许修改可观察变量
  @action AddUser(name) {
    this.userArray.push(name);
  }
}

const store = new UserStore();

// autorun会追踪userArrayRev的依赖
autorun(() => {
  console.log('反转后的用户列表:', store.userArrayRev);
});

// 调用3次AddUser,autorun会触发3次更新(加上初始化共4次)
store.AddUser('用户1');
store.AddUser('用户2');
store.AddUser('用户3');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:32:00