1

I have created a React context as follows (don't mind the any types. I'll deal with that later):

// File: AuthContext.ts
const AuthContext = React.createContext<AuthContextDataType | null>(null);

export default AuthContext;

I have then wrapped the whole app in the context provider as follows:

// 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>
  );
}

Now when I set the isAuthenticated variable in an async function in a component that uses the context variable and try to log it to console as follows:

authContext.setIsAuthenticated(true);
console.log(authContext.isAuthenticated);

I get the old value and not the newly set one. Why is this and how can I solve this problem?

Tommy Wolfheart
  • 440
  • 4
  • 16

1 Answers1

1

Setting the state in React acts like an async function.
Meaning that the when you set the state and put a console.log right after it, like in your example, the console.log function runs before the state has actually finished updating.

Which is why we have useEffect, a built-in React hook that activates a callback when one of it's dependencies have changed.

Example:

useEffect(() => {
   // Do whatever...
}, [authContext.isAuthenticated]

The callback will run only after the state has finished changing and a render has occurred.

tomleb
  • 2,409
  • 2
  • 9
  • 24