为什么在 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]

回调将 运行 只有在状态完成更改并发生渲染后。