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

mobx-state-tree修改currentUserStore报对象受保护错误如何解决

报错原因

mobx-state-tree 对状态修改做了强校验:只有同步执行的action代码块内拥有状态修改权限。你用async/await写的异步login逻辑,在await client.post(...)执行完成后,后续代码已经脱离了原action的同步执行上下文,这时候直接给currentUserStore.user赋值,会被判定为在action外部非法修改状态,直接抛出保护错误。

修复方案

官方推荐用内置的flow工具处理异步action,它基于generator实现,会自动维持整个异步流程的action上下文,不需要额外拆分方法。

修改后的完整代码:

import { types, flow } from "mobx-state-tree";
import { client } from '../../../helpers/client';

const User = types
  .model("User", {
    name: types.string,
    email: types.string,
    type: types.string,
    token: types.string,
    roles: types.array(types.string),
  })

export const CurrentUserStore = types
  .model("CurrentUserStore", {
    user: types.optional(types.maybeNull(User), () => null)
  })
  .actions((currentUserStore) => ({
    // 用flow包裹异步逻辑,替换原async声明
    login: flow(function* (login, password) {
      // 原await替换为yield
      const result = yield client.post(`auth`, {
        email: login,
        password,
      });

      const { name, email, type, token, roles } = result
      // 此处修改状态全程处于action上下文内,不会触发报错
      currentUserStore.user = User.create({ name, email, type, token, roles })
      localStorage.setItem('authUser', JSON.stringify(result));
    }),
    logout() {
      currentUserStore.user = null
      localStorage.removeItem('authUser')
    },
  }));

如果不想用flow,也可以把修改user、操作localStorage的逻辑抽成独立的同步action,在await拿到结果后调用这个同步action完成状态更新,这种写法也能绕过上下文丢失的问题,但代码冗余度更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:48:19