-1

I created an auth context and set the object to an initial state, then after wrapping the App() with the provider, I am trying to modify the authContext in 1 (Home.js) component and then try to access it on another component with the new state (Login.js) that I set it to be on the first component. I tested that the object is actually changing (user is set to { name: "omar", age: 23 } in Home.js, when I mount the login component (navigating to lh:3000/login), it seems that the authContext object is resetting to the initial state always. How can I solve this problem? Is it because when unmounting components in React the context variables are destroyed as well and when mounting a new component (that the context wraps) the context is remounted and re-initialized to the initial state?

index.js:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.js";
import { AuthContextProvider } from "./context/AuthContext.js";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <AuthContextProvider>
    <App />
  </AuthContextProvider>
);

app.js:

import Home from "./pages/Home/Home";
import { Profile } from "./pages/Profile/Profile";
import { Safak } from "./pages/Safak/Safak";
import { Login } from "./pages/Login/Login";
import { Signup } from "./pages/Signup/Signup";
import {
  BrowserRouter,
  createBrowserRouter,
  RouterProvider,
} from "react-router";
import { ErrorNotFound } from "./pages/ErrorNotFouns/ErrorNotFound";
import { noImage } from "./components/NoImage/noImage";

function App() {
  const router = createBrowserRouter([
    { path: "/", Component: Home },
    { path: "/noImage", Component: noImage },
    { path: "/logIn", Component: Login },
    { path: "/signUp", Component: Signup },
    { path: "/profile/:userID", Component: Profile },
    { path: "*", Component: ErrorNotFound },
  ]);

  return <RouterProvider router={router} />;
}

export default App;

Home.js

import "./home.css";
import { Topbar } from "../../components/TopBar/Topbar";
import { Feed } from "../../components/Feed/Feed";
import { LeftBar } from "../../components/LeftBar/LeftBar";
import { RightBar } from "../../components/RightBar/RightBar";
import { Posts } from "../../dummyData";
import axios from "axios";
import { use, useContext, useEffect, useState } from "react";
import { AuthContext } from "../../context/AuthContext";

export const Home = () => {
  const { auth, setAuth } = useContext(AuthContext);

  useEffect(() => {
    console.log(
      "this is the auth before the cahneg it has initail state",
      auth
    );

    setAuth({
      user: { name: "Omar", age: 23 },
      isFetching: false,
      error: false,
    });
  }, []);

  console.log("this is the auth after Omar logged in", auth);
  const [allFollowings, setAllFollowings] = useState([]);
  const [allPosts, setAllPosts] = useState([]);

  useEffect(() => {
    getallfollowings();
    getAllPosts();
  }, []);

  // useEffect(() => {
  //   console.log("this is coming from the all posts state var", allPosts);
  // }, [allPosts]);

  const getallfollowings = async () => {
    try {
      const res = await axios.get(
        "/api/user/followings/67b89df418f3af81ebd6f30b"
      );
      setAllFollowings(res.data);
    } catch (e) {
      console.log(e);
    }
  };

  const getAllPosts = async () => {
    try {
      const res = await axios.get(
        "/api/post/timeline/67b89dcc18f3af81ebd6f309"
      );
      setAllPosts(res.data);
    } catch (e) {
      console.log(e);
    }
  };

  return (
    <div>
      <Topbar />
      <div className="maincontent">
        <LeftBar allFollowings={allFollowings} />
        <Feed userPosts={allPosts} />
        <RightBar
          className={"rightbarHomepage"}
          pageType={"home"}
          allFollowings={allFollowings}
        />
      </div>
    </div>
  );
};

export default Home;

Login.js:

import React, { useContext, useEffect, useRef } from "react";
import { AuthContext } from "../../context/AuthContext";
import "./login.css";

export const Login = () => {
  const { auth, setAuth } = useContext(AuthContext);

  useEffect(() => {
    console.log("this is the auth context", auth);
  }, [auth]);

  console.log("this is the useref object", useRef(null));
  const emailRef = useRef(null);
  const passwordRef = useRef(null);

  const handleCkick = (e) => {
    e.preventDefault();
    console.log("clicked");
    console.log("this is the emai: ", emailRef.current.value);
    console.log("this is the pass: ", passwordRef.current.value);
    //api call to login the user.
  };

  return (
    <div className="logincontainer">
      <div className="loginwrapper">
        <div className="leftsection">
          <div className="leftcontainer">
            <div className="logoprofile">OmarScoial</div>
            <div className="slogan">
              Connect with Connect with freinds and the world around you on
              OmarSocial
            </div>
          </div>
        </div>
        <div className="rightsection">
          <div className="rightcontainercard">
            <form onSubmit={handleCkick}>
              <div className="cardwrapper">
                <input
                  placeholder="Email"
                  ref={emailRef}
                  type="email"
                  className="forminput"
                />
                <input
                  placeholder="Password"
                  ref={passwordRef}
                  type="password"
                  className="forminput"
                />
                <button type="submit" className="login">
                  Log In
                </button>
                <a href="" className="resetpassword">
                  Forgot Password?
                </a>
                <button type="button" className="signup">
                  Create a New Account
                </button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
};
3
  • How exactly are you "navigating" around your app, to get to "/login"? Are you just manually changing the URL in the browser's address bar? If so, then yeah, you are reloading the page which results in the app mounting again with all initial state values. You'll want to use the React-Router navigation functions and components to effect navigation actions via the client, e.g. Link, useNavigate, etc. If page reloads are an issue then you'll want to implement some state persistence so it isn't lost when the page is reloaded. Please edit to clarify the problem and reproduction steps. Commented Apr 21 at 22:08
  • thank you for sharing, yes you are right, my setup for the context provider and how i consume it is correct, but becasue i was changing the url i was demounting the component, now that i use the Link in react router, seems to be working fine. what is happening when i interact with the url directly? why is it not working when i do so? Commented Apr 22 at 19:14
  • It makes a page request to the server and loads (reloads) the page. When you use the client code React-Router intercepts the requests, but when you interact with the browser UI it can't. Commented Apr 22 at 19:35

1 Answer 1

-1

You're using React Router v6's createBrowserRouter with RouterProvider, which creates an entirely new React tree for every route. This bypasses the shared React context, including your AuthContextProvider.

That’s why your context gets reset on every route change.

The Fix: Instead of createBrowserRouter + RouterProvider, use the standard BrowserRouter + approach, like this:

// App.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home/Home";
import { Profile } from "./pages/Profile/Profile";
import { Safak } from "./pages/Safak/Safak";
import { Login } from "./pages/Login/Login";
import { Signup } from "./pages/Signup/Signup";
import { ErrorNotFound } from "./pages/ErrorNotFouns/ErrorNotFound";
import { noImage } from "./components/NoImage/noImage";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/noImage" element={<noImage />} />
        <Route path="/logIn" element={<Login />} />
        <Route path="/signUp" element={<Signup />} />
        <Route path="/profile/:userID" element={<Profile />} />
        <Route path="*" element={<ErrorNotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

Double-check that your AuthContextProvider looks something like this:

// AuthContext.js
import { createContext, useState } from "react";

export const AuthContext = createContext();

export const AuthContextProvider = ({ children }) => {
  const [auth, setAuth] = useState({
    user: null,
    isFetching: false,
    error: false,
  });

  return (
    <AuthContext.Provider value={{ auth, setAuth }}>
      {children}
    </AuthContext.Provider>
  );
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.