1

I have created AuthContext using React Context API. Where I am storing userData (initially from localStorage if I have data there and if not found in localStorage then after login).

export const AuthProvider = ({ children }) => {
  // const [loading, setLoading] = useState(true);
  const [userData, setUserData] = useState();
  useEffect(() => {
    const data = JSON.parse(localStorage.getItem('whatsappCloneData'))
    if (data) {
      setUserData(data);
    } else {
      setUserData();
    }
    // setLoading(false);
  }, [])

  return (
    <AuthContext.Provider value={{ userData, setUserData }}>
      {children}
    </AuthContext.Provider>
  )
}

In my app.js I'm checking if there is user details or not and based on that I am allowing user to visit protected routes.

const RequireAuth = () => {
  const { userData } = useContext(AuthContext);
  
  if (!userData) {
    return <Navigate to="/login" />
  }
  return <Outlet />;
}

function App() {
  return (
    <Router>
      <Container
        sx={{ backgroundColor: "white" }}
        maxWidth="xs" disableGutters={true} >
        <Routes>
          <Route path="/login" element={<Login />} />
          <Route path="/register" element={<Register />} />
          <Route element={<RequireAuth />}>
            <Route path="/profileInfo" element={<ProfileInfo />} />
            <Route path='/' element={
              <Home />
            }>
              <Route path='conversations' element={<Conversations />} />
              <Route path='status' element={<Status />} />
              <Route path="calls" element={<Calls />} />
            </Route>
            <Route path='/chat' element={<Chats />} />
            <Route path="/cam" element={<WebCam />} />
          </Route>
        </Routes>

        <ToastContainer
          position="bottom-right"
          autoClose={5000}
          hideProgressBar={false}
          newestOnTop={false}
          closeOnClick
          rtl={false}
          pauseOnFocusLoss
          draggable
          pauseOnHover
          theme="colored"
        />
      </Container>
    </Router >
}

In login page when user login then I am storing the user details in localStorage and in userData in authContext.

Everything works fine if I use button or links to navigate from public routes to protected route or protected routes to protected route if user is once logged in.

But once I refresh the page it went back to login page.

Reason behind this is that as I refresh the page authContext losses the userData so initially userData is undefined but just after few miliseconds when useEffect inside AuthContext complete it recover the userData from localStorage and sets back to userData. But as initially userData was undefined RequiredAuth in app.js navigate to login page.

How to solve this?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
iamTushar
  • 13
  • 3
  • Conditionally render anything ***other than*** the `Outlet` or `Navigate`, like a loading spinner, while `userData` is undefined. You can also directly initialize the `userData` state from localStorage with a lazy initialization function. – Drew Reese Feb 01 '23 at 09:38

0 Answers0