Home > OS >  How to Navigate to login page if he could not login?
How to Navigate to login page if he could not login?

Time:12-14

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 enter image description here

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>
  );
}
  • Related