i had created private route for home if the user not login and when he try to access the home page it has to navigate to login page but i am getting below error

and my code is App.js
import "./App.css";
import {
BrowserRouter as Router,
Route,
Routes,
Navigate,
} from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import BookingCar from "./pages/BookingCar";
import "antd/dist/antd.css";
import { protectedRoute } from "./components/ProtectedRoutes";
function App() {
return (
<div className="App">
<Router>
<Routes>
<Route
path="/"
exact
element={
<protectedRoute>
<Home />{" "}
</protectedRoute>
}
></Route>
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/bookingcar" element={<BookingCar />} />
</Routes>
</Router>
</div>
);
}
export default App;
protectedRoute.js
import { Route, Navigate } from "react-router-dom";
export function protectedRoute(props) {
if (localStorage.getItem("user")) {
return <Route {...props} />;
} else {
return <Navigate to="/login" />;
}
}
DefaultLayout.js
import React from "react"; import { Menu, Dropdown, Button, Space, Row, Col } from "antd";
function DefaultLayout(props) {
const user = JSON.parse(localStorage.getItem("user"));
const menu = (
<Menu>
<Menu.Item>
<a href="https://www.antgroup.com">Bookings</a>
</Menu.Item>
<Menu.Item>
<a href="https://www.aliyun.com">Profile</a>
</Menu.Item>
<Menu.Item
onClick={() => {
localStorage.removeItem("user");
window.location.href = "/login";
}}
>
<li>Logout</li>
</Menu.Item>
</Menu> ); return (
<div>
<div className="header bs1">
<Row gutter={16} justify="center">
<Col lg={20} sm={24} xs={24}>
<div className="d-flex justify-content-between">
<h1>SomuCars</h1>
<Dropdown overlay={menu} placement="bottomCenter">
<Button>{user.username}</Button>
</Dropdown>
</div>
</Col>
</Row>
</div>
<div>{props.children}</div>
</div> ); }
export default DefaultLayout;
How can i solve the problem
CodePudding user response:
The issue is that JSON.parse(localStorage.getItem("user")); returns null when there is nothing in localStorage to parse. user is null and so later when attempting to read user.username you see the error "can't read username of null` error.
You can either provide a backup value:
const user = JSON.parse(localStorage.getItem("user")) ?? {};
or use optional-chaining operator or null-check/guard-clause:
<Button>{user?.username}</Button>
<Button>{user && user.username}</Button>
Additionally, the protected route component is incorrectly named (React components are PascalCased) and is incorrectly directly rendering a Route component when it should be rendering the children prop. Specify the replace prop on the Navigate component if you want to redirect (i.e. REPLACE) instead of a normal PUSH navigation.
import { Navigate } from "react-router-dom";
export function ProtectedWrapper({ children }) {
if (localStorage.getItem("user")) {
return children;
} else {
return <Navigate to="/login" replace />;
}
}
Usage
function App() {
return (
<div className="App">
<Router>
<Routes>
<Route
path="/"
element={(
<ProtectedWrapper>
<Home />
</ProtectedWrapper>
)}
/>
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/bookingcar" element={<BookingCar />} />
</Routes>
</Router>
</div>
);
}
