I have implemented authorization in React. I want the user to not be able to go to other pages of the application without authorization. I created the following component.
import { ReactNode } from "react";
import { Navigate } from "react-router-dom";
import { useAuth } from "../hooks/use-auth";
interface ProtectedRouteProps {
children: ReactNode,
}
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
const { isAuth } = useAuth();
return !isAuth ? <Navigate to="/login" replace /> : <>{children}</>;
};
However, when going to authorization page in a reverse redirect, the child component is rendered for a few milliseconds. How to fix it?
<Route
path="/kanban"
element={
<ProtectedRoute>
<KanbanPage />
</ProtectedRoute>
}
/>
import { RootState, useAppSelector } from "../store";
export function useAuth() {
const { email, token, id } = useAppSelector((state: RootState) => state.user);
return {
isAuth: !!email,
email,
token,
id,
}
}
Auth logic
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
const auth = getAuth();
signInWithEmailAndPassword(auth, email, password)
.then(({ user }) => {
dispatch(setUser({
email: user.email,
id: user.uid,
token: user.refreshToken,
}));
setOpenSnackbar(true);
setTimeout(() => navigate('/kanban'), 2000)
})
.catch((error) => {
console.log(error);
});
}
redux:
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
email: null,
token: null,
id: null
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser(state, action) {
state.email = action.payload.email;
state.token = action.payload.token;
state.id = action.payload.id;
},
removeUser(state) {
state.email = null;
state.token = null;
state.id = null;
}
}
});
export const { setUser, removeUser } = userSlice.actions;
export default userSlice.reducer;
2
Answers
you have to enter the isAuth to useMemo and only when the isAuth will changed the component rerendered.
The
isAuth
is incorrectly returningtrue
orfalse
when the auth status isn’t known yet.Update the
setUser
reducer to set anisAuth
state value instead of coercing theemail
value to a boolean.Update
ProtectedRoute
to conditionally render null or a loading indicator when theisAuth
value isn’t set/determined yet.