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:
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:
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;
}