Company logo
  • Jobs
  • Bootcamp
  • About Us
  • For professionals
    • Home
    • Jobs
    • Courses
    • Questions
    • Teachers
    • Bootcamp
  • For business
    • Home
    • Our process
    • Plans
    • Assessments
    • Payroll
    • Blog
    • Calculator

0

49
Views
Updating state without triggering re-render of PrivateRoute

I have a react app with 1-hour login, and once the timer ran out, the next page change will popup a Modal, asking if user want to extend their time for another 1 hour, or logout. The Modal should only popup once.

So my attempt is:

  • use react-router-dom's useLocation() to detect every page change.
  • check time and check localStorage "IS_TOGGLE" to see if the Modal has popup yet.
  • if the user has timed out and IS_TOGGLE = 0, toggleModal();
  • else, logout.
const location = useLocation();
const [modal, setModal] = useState(false);

useEffect(() => {
  const isToggle = localStorage.getItem("IS_TOGGLE");
  const expiredTime = localStorage.getItem("EXPIRED_TIME");
  //check if toggled yet and expire yet
  if (
    isToggle === "0" &&
    expiredTime &&
    DateTime.fromISO(expiredTime).diffNow().toObject().milliseconds < 0
  ) {
    console.log("case 3");
    toggleModal();
  }
  console.log(location.pathname);
}, [location]);
function toggleModal() {
  localStorage.setItem("IS_TOGGLE", "1");
  setModal(true);
}

But the problem is, it seems toggleModal() trigger re-render, causing PrivateRoute to be called twice. The first time PrivateRoute is called, it returns children as expected, but the second time, because toggleModal() has just set IS_TOGGLE = "1", results in user logging out immediately.

My console.log result:

  • case 2
  • case 3
  • /dashboard
  • case 1
  • /login
const PrivateRoute = ({ children }) => {
    const { logout } = useAuth();
    const user = JSON.parse(localStorage.getItem('USER'));
    const accessToken = localStorage.getItem("ACCESS_TOKEN");
    const refreshToken = localStorage.getItem("REFRESH_TOKEN");
    const expiredTime = localStorage.getItem("EXPIRED_TIME");
    const isToggle = localStorage.getItem("IS_TOGGLE");

    if (typeof user === 'undefined' || user === null 
     || typeof accessToken === 'undefined' || accessToken === null 
     || typeof refreshToken === 'undefined' || refreshToken === null 
     || typeof expiredTime === 'undefined' || expiredTime === null
     || typeof isToggle === 'undefined' || isToggle === null || isToggle === "1") {
        logout();
        console.log("case 1");
        return <Navigate to="/login" />;
    };
    console.log("case 2");
    return children;
}
7 months ago ยท Juan Pablo Isaza
Answer question
Find remote jobs