Every time any component in the defined AppRoutes is rendered, it calls the getUser() hook and all the functions called when the component mounts twice which essentially means the component is rendered twice and i cant seem to figure out why.
Any insight would be really helpful.
Cheers!
I have a HomeContainer, which wraps the entire REACT project:
function HomeContainer() {
const { user, authenticated } = useUser();
const [toggled, setToggled] = useState(false);
const location = useLocation();
// const showHeader = !!location.pathname.endsWith("recording");
const showHeader = recordingPathRegex.test(location.pathname);
return (
<Box>
{user && authenticated ? <>
<AppHeader user={user} setToggled={setToggled} toggled={toggled} reducedHeader={showHeader} />
<Box sx={styles.container}>
<Box sx={{ display: { md: 'none' } }}><SideNav toggled={toggled} setToggled={setToggled}/></Box>
<Box component={'main'} sx={styles.mainSection}>
<AppRoutes user={user} />
</Box>
</Box>
</> :
<Box component={'main'} sx={styles.mainSection}>
<AppRoutes user={null}/>
</Box>
}
</Box>
)
}
export default HomeContainer
that uses a custom hook for authentication for app routes. The useUser hook below, which checks if authenticated return an object with {user, authenticated} value:
export function useUser() {
const [user, setUser] = useState(null);
const [authenticated, setAuthenticated] = useState(false);
const navigate = useNavigate();
const location = useLocation();
const subscribe = location.pathname.split("/")[1]
useEffect(() => {
async function getUserDetails() {
const { authenticated, user } = await getAuthenticatedUser();
if (!authenticated && location.pathname !== '/signup') {
navigate('/signin');
return;
}
else if (authenticated && (location.pathname === '/signup' || location.pathname === '/signin')) {
navigate('/meetings');
return;
}
setUser(user);
setAuthenticated(authenticated);
}
getUserDetails();
}, [navigate]);
return { user, authenticated };
}
it uses a getAuthenticatedUser function and looks for an auth token saved in the browsers localStorage, if not found it requests for one as below:
export async function getAuthenticatedUser() {
const defaultReturnObject = { authenticated: false, user: null };
try {
const token = getTokenFromLocalStorage();
if (!token) {
return defaultReturnObject;
}
const response = await axios({
method: 'GET',
url: API_ROUTES.GET_USER,
headers: {
Authorization: `Token ${token}`
}
});
const authenticated = response.data.status;
return authenticated ? {authenticated: response.data.status, user: response.data.data} : false;
}
catch (err) {
console.log('getAuthenticatedUser, Something Went Wrong', err);
localStorage.clear();
window.location.reload();
return defaultReturnObject;
}
}
the AppRoutes are defined for which ones are accessible for authenticated users i.e. they are logged in, and the others which are accessible i.e the landing page etc..
function AppRoutes(props) {
const { user } = props;
return (
<>
{user ? <Routes>
<Route path='/dashboard' element={<Dashboard />} />
...
</Routes>
: <Routes>
<Route path='' element={<LandingPage />} />
<Route path='/signin' element={<Signin />} />
<Route path='/signup' element={<Signup />} />
<Route path='/reset-password' element={<ForgotPassword />} />
<Route path='/faq' element={<FAQ />} />
</Routes>
}
</>
)
}
export default AppRoutes