'Redux store takes lil bit time to update store which causes else block to execute and hence get redirected to unintended page

//PrivateAuthComponent.js
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useRouter } from "next/router";

const PrivateAuth = ({ children }) => {
  const router = useRouter();
  const [userLoaded, setUserLoaded] = useState(false);
  const userExists = useSelector((state) => state.user);

  console.log("User in private auth", userExists);

  useEffect(() => {
   
    if (userExists && userExists.token) {
      setUserLoaded(true);
    } else {
      router.replace("/login");
      setUserLoaded(false);
    }
  }, []);

  return userLoaded && <>{children}</>;
};

export default PrivateAuth;

//UserHistory.js
import React from "react";
import PrivateAuth from "../../auth/privateAuth";

const history = () => {
  return (
    <PrivateAuth>
      <div className="container-fluid">
        <div className="row">User Page</div>
      </div>
    </PrivateAuth>
  );
};

export default history;

I am trying to wrap some pages so that they can't be accessed by users who are not logged in. When I login, I get redirected to user/history page as intended. But I manually want to go to user/history for the second time, the page reloads and what happens is redux store takes a bit time to update itself, but that code inside useEffect runs before this happens which causes that block inside else to run. So I get redirected to "/login" page because users don't exist yet and hence never get back to the user/history page as intended even when I am logged in and redux store is updated. What can I do about this?



Solution 1:[1]

I would suggest adding a loading state when the API call is happening,

Loading is true show loader If the user does not exist redirect to /login else render children

const PrivateAuth = ({ children }) => {
  const { user, loading } = useSelector((state) => state);
  if (loading) return <Loader />;
  if (!user) return <Redirect to="/login" />;
  return <>{children}</>;
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rahul Sharma