MobX:由于启用了严格模式,因此不允许在不使用操作的情况下更改(观察到的)可观察值
MobX: Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed
我的上下文是这样的:
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] Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: 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)
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 = authUser
}
}
关于异步操作的更多信息(您甚至可以使用生成器!):https://mobx.js.org/actions.html#asynchronous-actions
在 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
}
我的上下文是这样的:
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] Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: 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)
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 = authUser
}
}
关于异步操作的更多信息(您甚至可以使用生成器!):https://mobx.js.org/actions.html#asynchronous-actions
在 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
}