Home > OS >  React Context doesnt Save global state Typescript from childcomponent
React Context doesnt Save global state Typescript from childcomponent

Time:08-25

trying to use react context to save a userStatus context globally

code is as follows:

app.tsx

function App() {
  const [userStatus, setUserStatus] = React.useState(UserStatus.LoggedOff);
  console.log("userStatus is "   userStatus);

  return (
    <UserStatusContext.Provider value={{ userStatus, setUserStatus }}>
      <Router>
        <div className="App">
          <h1>Ping Messenger</h1>
          <Routes>
            <Route path="/login" element={<LoginPage />} />
            <Route path="/register" element={<RegisterPage />} />
            <Route path="/" element={<Hub />} />
          </Routes>
        </div>
      </Router>
    </UserStatusContext.Provider>
  );
}

context.tsx

import { createContext, useContext } from "react";

export enum UserStatus {
  LoggedIn = 0,
  LoggedOff = 1,
}

export type UserStatusContextType = {
  userStatus: UserStatus;
  setUserStatus: (userStatus: UserStatus) => void;
};

export const UserStatusContext = createContext<UserStatusContextType>({
  userStatus: UserStatus.LoggedOff,
  setUserStatus: (userStatus) => console.warn("log on status unknown"),
});

export const useUserStatus = () => useContext(UserStatusContext);

and my loginPage.tsx

const LoginPage = () => {
...
 const { userStatus, setUserStatus } = useUserStatus();


    var loginSuccess = await authService.login(credentials);

    if (loginSuccess) {
      setUserStatus(UserStatus.LoggedIn);
   }
...

now, when I console log around, in my app.tsx file, console.log("userStatus is " userStatus);

when navigating to '/login' it logs 'userStatus is 0'

when submitting the form it briefly logs 'userStatus is 1' (this is the desired output) but when the page compltes / refreshing or i navigate to '/' it log 'userStatus is 0'. it doesnt appear to be saving and persisting the state.

any ideas?

CodePudding user response:

If you are manually editing the URL in the browser's address bar this is reloading the page, which reloads the React app, e.g. remounts the entire app. All React state resides only in memory, so when the app remounts all state is reset.

This is an issue of state persistence, i.e. persisting the userStatus state through page reloads. For this you could persist/initialize userStatus to/from localStorage.

Example:

function App() {
  const [userStatus, setUserStatus] = React.useState(
    // initial value from localStorage or default value
    JSON.parse(localStorage.getItem("userStatus")) ?? UserStatus.LoggedOff
  );

  useEffect(() => {
    console.log("userStatus is "   userStatus);
    // persist userStatus state changes to localStorage
    localStorage.setItem("userStatus", JSON.stringify(userStatus));
  }, [userStatus]);
  
  return (
    <UserStatusContext.Provider value={{ userStatus, setUserStatus }}>
      <Router>
        <div className="App">
          <h1>Ping Messenger</h1>
          <Routes>
            <Route path="/login" element={<LoginPage />} />
            <Route path="/register" element={<RegisterPage />} />
            <Route path="/" element={<Hub />} />
          </Routes>
        </div>
      </Router>
    </UserStatusContext.Provider>
  );
}
  • Related