Home > Software engineering >  How can I change the value of a context without it resetting after a page change in Ionic React?
How can I change the value of a context without it resetting after a page change in Ionic React?

Time:09-22

I'm using useContext to know if a user has logged in, and store the credentials if so. However when I change component the object seems to reset to the default value, making it useless. The idea was taken from https://stackoverflow.com/a/62362139, however it doesn't work.

UserContext.tsx

import { createContext } from "react";

interface UserManager {
  username: string;
  password: string;
  setIsLoggedIn: Function;
}

const user: UserManager = {
  username: "",
  password: "",
  setIsLoggedIn: () => {}
};

App.tsx

const App: React.FC = () => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const user = useContext(UserContext);
  user.setIsLoggedIn = setIsLoggedIn;

  return (
    <UserContext.Provider value={user}>
      <IonApp>
        <IonReactRouter>
          <IonRouterOutlet>
            <Route exact path="/login" component={Login}/>
            <Route exact path="/register" component={Register}/>
            <Route exact path="/user_info" component={UserInfo}/>
            <Route exact path="/main_tabs" component={MainTabs}/>
            <Redirect exact from="/" to={isLoggedIn ? "/main_tabs" : "/login"}/>
          </IonRouterOutlet>
        </IonReactRouter>
      </IonApp>
    </UserContext.Provider>
  );
};

Login.tsx

const Login: React.FC = () => {
  const user = useContext(UserContext);
  const [username, setUsername] = useState<string>("");
  const [password, setPassword] = useState<string>("");

  const login = () => {
    if (username !== "" && password !== "") {
      let body = {
        username: username,
        password: password
      };
      let request = sendRequest('POST', '/login', body);
      request.onreadystatechange = () => {
        if (request.readyState === 4) {
          let response = JSON.parse(request.response);
          if (response.success) {
            user.username = username;
            user.password = password;
            user.setIsLoggedIn(true);
            window.location.href = "/main_tabs"; // user will reset after this page change
          } else if (!response.success) {
            alert("Incorrect password");
          }
        }
      };
    } else {
      alert("Fill in both fields");
    }
  };

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Concepimento</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
        <IonInput type="email" placeholder="Email" onIonChange={e => setUsername(e.detail.value!)} required clearInput></IonInput>
        <IonInput type="password" placeholder="Password" onIonChange={e => setPassword(e.detail.value!)} required clearInput></IonInput>
        <IonText onClick={() => window.location.href = "/main_tabs"}>Password dimenticata?</IonText>
        <br /><br /><br />
        <IonButton onClick={login}>
          Login
        </IonButton>
        <br /><br /><br />
        <IonText>
          Prima volta?
        </IonText>
        <br />
        <IonButton href="/register">
          Registrati Qui
        </IonButton>
      </IonContent>
    </IonPage>
  );
};

I believe the problem is that when I import UserContext to access its values, the user object gets reinitialised (I put a print statement which confirms this). I've looked around but all sources only talk about accessing from child components, never modifying the default values. How do I do this?

CodePudding user response:

window.location.href = "/main_tabs"

you should not be using location.href in the application...

history.push("/main_tabs");

in you function

const history = useHistory();
  • Related