I am working on a basic app with React, Redux and React Router 7. This app has a /profile route which is protected. If you go on a protected route without being logged in, you are redirected to /login. This is working fine. The problem is that i need it to be so that when the user logs out, they are redirected to the homepage; and currently when logging out on the profile page, it redirects to the login page.
here is my App.jsx :
function App() {
const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);
const userToken = useSelector((state) => state.auth.userToken);
const dispatch = useDispatch();
useEffect(() => {
if (isLoggedIn && userToken) {
dispatch(fetchUser(userToken));
}
}, [isLoggedIn, userToken, dispatch]);
return (
<Router>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="login" element={<LogIn />} />
<Route
path="profile"
element={
<ProtectedRoute isLoggedIn={isLoggedIn}>
<Profile />
</ProtectedRoute>
}
/>
</Route>
</Routes>
</Router>
);
}
ProtectedRoute.jsx :
import { Navigate } from "react-router";
export default function ProtectedRoute({ children, isLoggedIn }) {
if (isLoggedIn) {
return children;
} else {
return <Navigate to="/login" />;
}
}
Relevant part from my authSlice :
const initialState = {
userToken: null,
isLoggedIn: false,
error: null,
loading: false,
};
const authSlice = createSlice({
name: "auth",
initialState,
reducers: {
logout: () => initialState,
},
extraReducers: (builder) => {
builder
.addCase(login.pending, (state) => {
state.loading = true;
})
.addCase(login.fulfilled, (state, action) => {
state.loading = false;
state.error = null;
state.isLoggedIn = true;
state.userToken = action.payload;
})
.addCase(login.rejected, (state, action) => {
state.loading = false;
state.error = action.payload;
});
},
});
Layout.jsx :
function Layout() {
return (
<>
<Header />
<Outlet />
<Footer />
</>
);
}
Header.jsx, where i'm dispatching my logout action and trying to do my redirect :
function Header() {
const navigate = useNavigate();
const dispatch = useDispatch();
const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);
const userFirstName = useSelector((state) => state.user.infos?.firstName);
function handleLogoutClick() {
navigate("/");
dispatch(logout());
}
let nav = "";
if (isLoggedIn) {
nav = (
<div>
<NavLink className="main-nav-item" to="/profile">
<i className="fa fa-user-circle"></i> {userFirstName}
</NavLink>
<button className="main-nav-item" onClick={handleLogoutClick}>
<i className="fa fa-sign-out"></i> Sign Out
</button>
</div>
);
} else {
nav = (
<div>
<NavLink className="main-nav-item" to="/login">
<i className="fa fa-user-circle"></i> Sign In
</NavLink>
</div>
);
}
return (
<nav className="main-nav">
<NavLink className="main-nav-logo" to="/">
<img className="main-nav-logo-image" src={logo} alt="logo" />
<h1 className="sr-only">Test</h1>
</NavLink>
{nav}
</nav>
);
I don't know why the navigate("/") in my handleLogoutClick function is always ignored. I'm calling navigate to navigate to the homepage before login out, so when logout is called i should already be on an unprotected route, so why the redirected to /login after login out ?