MobX:由于启用了严格模式,不允许在不使用操作的情况下更改(观察到的)可观察值



我的上下文如下所示:

class AuthStoreClass {
authUser = null
constructor() {
makeAutoObservable(this)
}
login = async (params) => {
const { data: { data: authUser } } = await loginUser(params)
this.authUser = authUser
}
}
const AuthStoreContext = React.createContext(null);
export const authStoreObject = new AuthStoreClass()
export const AuthStoreProvider = ({ children }: any) => {
return <AuthStoreContext.Provider value={authStoreObject}>{children}</AuthStoreContext.Provider>;
};
export const useAuthStore = () => {
return React.useContext(AuthStoreContext);
};

我在组件的其他地方使用上下文:

const LoginPage = observer(() => {
const authStore = useAuthStore()
...
authStore.login(...)

最后一行报告以下警告:

[MobX]由于启用了严格模式,因此不允许在不使用操作的情况下更改(观察到的(可观察值。尝试修改:AuthStoreClass@1.authUser

一切如预期。如何解决此问题?

您的login函数是async,您需要在内部使用runInAction,或者在单独的操作中处理结果,或者使用其他处理异步操作的方法:

import { runInAction, makeAutoObservable } from "mobx"
class AuthStoreClass {
authUser = null
constructor() {
makeAutoObservable(this)
}
login = async (params) => {
const { data: { data: authUser } } = await loginUser(params)

// Wrap all changes with runInAction
runInAction(() => {
this.authUser = authUser
})
// or do it in separate function
this.setUser(authUser)
}
// This method will be wrapped into `action` automatically by `makeAutoObservable`
setUser = (user) => {
this.authUser = user
}
}

这是因为,引用文档,在异步过程中更新可观察性的每一步("tick"(都应该标记为动作。并且第一个CCD_ 4之前的代码处于不同的";勾号";而不是CCD_ 5之后的代码。

关于异步操作的更多信息(您甚至可以使用生成器!(:https://mobx.js.org/actions.html#asynchronous-行动

在MobX版本6中,默认情况下强制执行操作,但您可以使用configure方法禁用警告:

import { configure } from "mobx"
configure({
enforceActions: "never",
})

但是要小心,enforceActions的目标是不要忘记将事件处理程序和所有突变封装在action中。不这样做可能会导致观察者的额外重新运行。例如,如果在某个处理程序中更改两个值而不执行操作,则组件可能会重新渲染两次而不是一次。makeAutoObservable自动包装所有方法,但仍需要手动处理async方法和Promises

您还可以更改函数以使用yield语法,从而不需要runInAction

*login() {
const { data: { data: authUser } } = yield loginUser(params)
this.authUser = authUser
}

另一种可能的解决方案是在类构造函数中定义方法,并将其声明为action

constructor() {
makeAutoObservable(this, {
login: action
})
}

将{action,makeAutoObservable}从";mobx";;

class AuthStoreClass {
authUser = null
constructor() {
makeAutoObservable(this, {
login: action
})
}
login = async (params) => {
const { data: { data: authUser } } = await loginUser(params)
this.authUser = authUser
}
}

最新更新