Выгрузка данных из localStorage ReactJS

Столкнулся с проблемой выгрузки из localStorage возможно даже с пониманием работы самого React, а именно

import "bootstrap/dist/css/bootstrap.min.css";
import { React, useState, useContext } from "react";
import {
  Form,
  Row,
  InputGroup,
  Col,
  Button,
  Container,
  Card,
} from "react-bootstrap";
import { AuthContext } from "../components/AuthContext.jsx";
import { Navigate } from "react-router-dom";

function LoginPage() {
  const { setOperator } = useContext(AuthContext);
  const [validate, setValidate] = useState(true);
  const [formData, setFormData] = useState({ login: "", pass: "" });

  const handleChange = (event) => {
    setFormData({ ...formData, [event.target.name]: event.target.value });
  };

  const handleButton = () => {
    fetch("/set_operator", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        login: formData.login,
        pass: formData.pass,
      }),
    })
      .then((res) => res.json())
      .then((userData) => {
        /*   console.log(userData); */
        if (userData.error === "User is not found") {
          return console.log(userData);
        }

        setOperator(userData.operator);
        localStorage.setItem("currentUser", JSON.stringify(userData.operator));
      });
  };

  const checkStorage = localStorage.hasOwnProperty("currentUser");

  if (checkStorage) {
    return <Navigate to={"/admin"} />;
  }

  return (
    <Container>
      <Row className="justify-content-center align-items-center g-4">
        <Col xs={5}>
          <Card border="primary" style={{ width: "35rem" }}>
            <Card.Header className="text-center">Authentication</Card.Header>
            <Form noValidate validated={validate} /* onSubmit={handleSubmit} */>
              <Row className="mb-3">
                <Form.Group
                  as={Col}
                  md="7"
                  controlId="validationCustomUsername"
                >
                  <Form.Label>Username</Form.Label>
                  <InputGroup hasValidation>
                    <InputGroup.Text id="inputGroupPrepend">@</InputGroup.Text>
                    <Form.Control
                      required
                      type="text"
                      placeholder="login"
                      name="login"
                      value={formData.login}
                      onChange={handleChange}
                    />
                    <Form.Control.Feedback>
                      Username is a required field{" "}
                    </Form.Control.Feedback>
                  </InputGroup>
                </Form.Group>
              </Row>
              <Row className="mb-3">
                <Form.Group as={Col} md="7" controlId="validationCustomPass">
                  <Form.Label>Password</Form.Label>
                  <Form.Control
                    required
                    type="text"
                    placeholder="password"
                    name="pass"
                    value={formData.pass}
                    onChange={handleChange}
                  />
                  <Form.Control.Feedback>
                    Password is a required field{" "}
                  </Form.Control.Feedback>
                </Form.Group>
              </Row>
              <Button onClick={handleButton} href="/admin">
                Login
              </Button>
            </Form>
          </Card>
        </Col>
      </Row>
    </Container>
  );
}

export default LoginPage;

тут происходит запись в localStorage работает криво, постоянно ловлю ошибки с зацикливанием, далее я хочу получать данные из localStorage посредствам useContext и reducer Мой Context:

import React, { createContext, useReducer, useEffect } from "react";
import { reducerUsers } from "./ReducerUsers";

export const AuthContext = createContext();

const initialState = {
  operators: null,
};

export const AuthProvider = ({ children }) => {
  const [value, dispatch] = useReducer(reducerUsers, initialState);

  useEffect(() => {
    dispatch({ type: "CHECK_LOCAL_STORAGE" });
  }, [children]);

  value.setOperator = (operatorData) => {
    dispatch({ type: "SET_OPERATOR", payload: operatorData });
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

И тут мой reducer

export function reducerUsers(state, { type, payload }) {
  switch (type) {
    case "SET_OPERATOR":
      return {
        ...state,
        operators: payload || [],
      };
    case "CHECK_LOCAL_STORAGE":
      const storedUser = JSON.parse(localStorage.getItem("currentUser"));
      if (storedUser) {
        return {
          ...state,
          operators: storedUser,
        };
      }
      return state;
    default:
      return state;
  }
}

Далее я создаю приватный маршрут в котором прописываю следующее:

import React, { useContext } from "react";
import { Outlet, Navigate } from "react-router-dom";
import { AuthContext } from "../components/AuthContext";

export const PrivateRoute = ({
  element: Element,
  currentUser,
  roles,
  ...rest
}) => {
  const { operators } = useContext(AuthContext);
  console.log(operators);
  if (!currentUser) {
    // console.log(currentUser);
    return <Navigate to="/login" />;
  }

  if (roles && !roles.includes(currentUser[0].role)) {
    // console.log(`${currentUser[0].role} ${roles}`);
    return <Navigate to="*" />;
  }

  return (
    <Outlet>
      <Element {...rest} />
    </Outlet>
  );
};

Не смотрите что проверки сейчас реализованы через props это просто как затычка от безысходности... Но если посмотреть в консоль console.log(operators); то первым делом я получаю null а потом массив данных

0 : id : 1 img : null login : "admin" name : "Alen" pass : "admin" role : "admin" [[Prototype]] : Object length : 1 [[Prototype]] : Array(0)

соответственно я не могу дальше произвести не какие проверки так как ловлю ошибку сразу же при переходе или обновлении страницы. Ну и в завершении мой App для полной картины вызова

import React, { useState } from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { ProductsContext } from "./components/ProductsContext.jsx";
import { AuthProvider } from "./components/AuthContext.jsx";
import { PrivateRoute } from "./components/PrivateRoute.jsx";

import Navibar from "./components/NaviBar.jsx";
import LoginPage from "./pages/LoginForm.jsx";
import Notfoundpage from "./pages/Notfoundpage.jsx";
import Infoproduct from "./pages/Infoproduct.jsx";
import Productpage from "./pages/Productpage.jsx";
import { PaymentPage } from "./pages/Payment.jsx";
import { BucketList } from "./pages/BucketList.jsx";
import { OrderSuccessPage } from "./pages/OrderSuccess.jsx";
import FoodDrink from "./pages/FoodDrink.jsx";
import AdminPage from "./pages/AdminPage.jsx";
import { AddProduct } from "./pages/AddProduct.jsx";
import { Orders } from "./pages/Orders.jsx";
import { ProductList } from "./pages/ProductList.jsx";
import Sidebar from "./components/SideBar.jsx";

function App() {
  const [currentUser, setCurrentUser] = useState(
    JSON.parse(localStorage.getItem("currentUser"))
  );
  return (
    <>
      <AuthProvider>
        <ProductsContext>
          <Router>
            <Navibar />
            <Sidebar />
            <Routes>
              <Route path="/" element={<Productpage />} />
              <Route path="product/:id" element={<Infoproduct />} />
              <Route path=":typeParam" element={<FoodDrink />} />
              <Route path="payment" element={<PaymentPage />} />
              <Route path="bucket" element={<BucketList />} />
              <Route path="order_success" element={<OrderSuccessPage />} />
              <Route path="login" element={<LoginPage />} />

              <Route
                path="/admin"
                element={
                  <PrivateRoute
                    element={AdminPage}
                    roles={["admin", "moderator"]}
                    currentUser={currentUser}
                  />
                }
              />
              <Route path="/admin/add_product" element={<AddProduct />} />
              <Route path="/admin/orders" element={<Orders />} />
              <Route path="/admin/product_list" element={<ProductList />} />
              <Route path="*" element={<Notfoundpage />} />
            </Routes>
          </Router>
        </ProductsContext>
      </AuthProvider>
    </>
  );
}

export default App;

Помогите пожалуйста разобраться что я делаю не так, как сделать лучше ? Я только изучаю React и не понимаю в чём главноя моя ошибка. Буду очень благодарен за любую помощь Версия react: "react": "^18.2.0" Версия react-router-dom: "react-router-dom": "^6.11.1"

Так же я постарался реализовать пример на codesandbox Мой пример с ошибкой


Ответы (0 шт):