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
相关产品推荐
相关产品推荐

