为什么在 React 中上下文变量(状态)不立即更新?
Why isn't context variable (state) updated immediately in React?
我已经创建了一个 React context 如下(不要介意任何类型。我稍后会处理):
// File: AuthContext.ts
const AuthContext = React.createContext<AuthContextDataType | null>(null);
export default AuthContext;
然后我将整个应用程序包装在上下文提供程序中,如下所示:
// File: _app.ts
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const [user, setUser] = React.useState(null);
// Sign out the user, memoized
const logout = React.useCallback(() => {
setIsAuthenticated(false);
setUser(null);
}, []);
// Memoize the full context value
const authContextValue = React.useMemo(
() => ({
isAuthenticated,
setIsAuthenticated,
user,
setUser,
logout,
}),
[isAuthenticated, setIsAuthenticated, user, setUser, logout]
);
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return (
<AuthContext.Provider value={authContextValue}>
{getLayout(<Component {...pageProps} />)};
</AuthContext.Provider>
);
}
现在,当我在使用上下文变量的组件中的异步函数中设置 isAuthenticated
变量并尝试将其记录到控制台时,如下所示:
authContext.setIsAuthenticated(true);
console.log(authContext.isAuthenticated);
我得到的是旧值,而不是新设置的值。为什么会这样,我该如何解决这个问题?
在 React 中设置状态就像一个异步函数。
这意味着当您设置状态并在它之后放置一个 console.log
时,就像在您的示例中一样,console.log
函数 运行s 在状态实际完成更新之前。
这就是为什么我们有 useEffect
,一个 built-in React 挂钩,当其中一个依赖项发生变化时会激活回调。
示例:
useEffect(() => {
// Do whatever...
}, [authContext.isAuthenticated]
回调将 运行 只有在状态完成更改并发生渲染后。
我已经创建了一个 React context 如下(不要介意任何类型。我稍后会处理):
// File: AuthContext.ts
const AuthContext = React.createContext<AuthContextDataType | null>(null);
export default AuthContext;
然后我将整个应用程序包装在上下文提供程序中,如下所示:
// File: _app.ts
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const [user, setUser] = React.useState(null);
// Sign out the user, memoized
const logout = React.useCallback(() => {
setIsAuthenticated(false);
setUser(null);
}, []);
// Memoize the full context value
const authContextValue = React.useMemo(
() => ({
isAuthenticated,
setIsAuthenticated,
user,
setUser,
logout,
}),
[isAuthenticated, setIsAuthenticated, user, setUser, logout]
);
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return (
<AuthContext.Provider value={authContextValue}>
{getLayout(<Component {...pageProps} />)};
</AuthContext.Provider>
);
}
现在,当我在使用上下文变量的组件中的异步函数中设置 isAuthenticated
变量并尝试将其记录到控制台时,如下所示:
authContext.setIsAuthenticated(true);
console.log(authContext.isAuthenticated);
我得到的是旧值,而不是新设置的值。为什么会这样,我该如何解决这个问题?
在 React 中设置状态就像一个异步函数。
这意味着当您设置状态并在它之后放置一个 console.log
时,就像在您的示例中一样,console.log
函数 运行s 在状态实际完成更新之前。
这就是为什么我们有 useEffect
,一个 built-in React 挂钩,当其中一个依赖项发生变化时会激活回调。
示例:
useEffect(() => {
// Do whatever...
}, [authContext.isAuthenticated]
回调将 运行 只有在状态完成更改并发生渲染后。