I am new in React
and React router
. My problem is, after click on Login button, Home component
does not render. It justs replace url
adress from "/" to "/home".
Packages are all installed right. I have checked this out in Network in DevTools, and it really does not render Home component
Why it is happening?
AppRoutes.js
const AppRoutes = [
{
index: true,
path: "/",
element: <Layout />
},
{
path: "/home",
element: <Home/>
}
];
export default AppRoutes;
Layout.jsx
const Layout = () => {
const [userId, setUserId] = useState(null);
const navigate = useNavigate();
const getUserIdFromLocalStorage = async () => {
const id = await localStorage.getItem('userId');
if (!id) {
navigate('/');
} else {
setUserId(id);
}
};
useEffect(() => {
getUserIdFromLocalStorage();
}, []);
return (
<>
{userId ? (
<>
<Sidebar />
</>
) : (
<LoginPage />
)}
</>
);
}
export default Layout;
LoginPage
const LoginPage = () => {
const navigate = useNavigate();
const redirectToHome = () => {
navigate('/home',
{
replace: true
});
}
return (
<div className="bg-dark text-white">
<button onClick={redirectToHome}>Login</button>
</div>
);
}
export default LoginPage;
App
export default class App extends Component {
static displayName = App.name;
render() {
return (
<Routes>
<Route element={<Layout />}>
{AppRoutes.map((route, index) => {
const { path, element } = route;
return <Route key={index} path={path} element={element} />;
})}
</Route>
</Routes>
);
}
}
2
Answers
There are two issues.
Issue
The issue here is that you are rendering
Layout
on a layout route, e.g. a route that renders nested routes, andLayout
is not rendering anOutlet
component for the nested routes to render theirelement
content into.Suggested Solutions
You have a few options:
Layout
to render anOutlet
so the nested routes can also be outputted. Remove the layout route fromAppRoutes
.Layout
as a regular route component and remove the "parent" layout route.Between the two I believe you really want to keep
Layout
as a layout route. Refactor it to render theSidebar
and anOutlet
or a redirect to a"/login"
route that rendersLogin
.or convert
App
to a React function component and use theuseRoutes
hook. No need to reinvent the wheel of mapping/rendering routes.