Невозможно увидеть товары в корзине с помощью «набора инструментов Redux»

Я делал небольшой проект реагирования, в котором хотел использовать «Инструментарий Redux» для логики своей корзины.

Что я хочу :

Когда я нажму кнопку «Добавить в корзину», она должна добавить (количество, цвет, имя, название компании и т. д.) в корзину как 1 товар.

И когда я открою страницу корзины, она должна ее отобразить.

Вот мой код Redux:

Индекс.js

import { Provider } from "react-redux";
import { store } from "./Redux/Store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <>
    <Provider store = {store}>
      <App />
    </Provider>
  </>
);     

Магазин.js

import { configureStore } from "@reduxjs/toolkit";
import cartReducer from "./Slices/CartSlices";

export const store = configureStore({
  reducer: {
    cart1: cartReducer,
  },
});

CartSlices.js

import { createSlice } from "@reduxjs/toolkit";

const cartSlice = createSlice({
  name: "Cart",
  initialState: [],
  reducers: {
    addItem: (state, action) => {
      state.push(action.payload);
    },
  },
});
export const { addItem } = cartSlice.actions;
export default cartSlice.reducer;

SingleProduct.js

import React, { useEffect, useState } from "react";
import { Link, useLocation } from "react-router-dom";
import "./SingleProduct.css";
import { addItem } from "../Redux/Slices/CartSlices";
import { useDispatch } from "react-redux";

function SingleProduct() {
  const location = useLocation();
  const productData = location.state?.data;
  const dispatch = useDispatch();

  const [selectedColorIndex, setSelectedColorIndex] = useState(null);
  const [selectedQuantity, setSelectedQuantity] = useState(0);

  const QuantitySelect = () => {
    const options = Array.from({ length: 10 }).map((_, i) => (
      <option key = {i} value = {i}>
        {i}
      </option>
    ));
    return options;
  };

  return (
    <section>
      <div className = "row">
        <div className = "col-md-6">
          <img
            src = {productData.attributes.image}
            alt = ""
            className = "mt-5 rounded-5 ms-5 shadow"
            style = {{
              objectFit: "cover",
              height: "400px",
              width: "550px",
            }}
          />
        </div>
        <div className = "col-md-6 mt-5">
          <h2 className = "fw-bold">{productData.attributes.title}</h2>
          <h5 className = "fw-bold text-black-50 mt-3">
            {productData.attributes.company}
          </h5>
          <p className = "mt-3">
            <span>$</span>
            {productData.attributes.price}
          </p>
          <p className = "lead fs-6 fw-light lh-lg">
            {productData.attributes.description}
          </p>
          <div>
            <p className = "fw-bold"> Colors</p>
            <div className = "d-flex">
              {productData.attributes.colors.map((color, index) => (
                <div
                  key = {index}
                  className = {`dot ${
                    selectedColorIndex === index ? "selected-dot" : ""
                  }`}
                  style = {{ backgroundColor: color }}
                  onClick = {() => setSelectedColorIndex(index)}
                ></div>
              ))}
            </div>
            <div>
              <p className = "mt-3 fw-bold">Quantity</p>
              <select
                className = "form-select w-50 rounded-3"
                value = {selectedQuantity}
                onChange = {(e) => setSelectedQuantity(e.target.value)}
              >
                <QuantitySelect />
              </select>
            </div>

             {/* <Link to = {"/cart"}> */}
              <div
                className = "btn mt-4 text-white"
                style = {{ backgroundColor: "#463aa1", height: "40px" }}
                onClick = {(e) =>
                  dispatch(
                    addItem({
                      image: productData.attributes.image,
                      companyName: productData.attributes.company,
                      price: productData.attributes.price,
                      title: productData.attributes.title,
                      color: selectedColorIndex,
                      quantity: selectedQuantity,
                    })
                  )
                }
              >
                Add To Bag
              </div>
          {/* </Link> */}
          </div>
        </div>
      </div>
      {/* Empty div for space */}
      <div style = {{ height: "50px" }}></div>
    </section>
  );
}

export default SingleProduct;

Карт.js

import { useSelector } from "react-redux";
function Cart() {
  const items = useSelector((state) => state);

  console.info("Items : ", items);
  // render code
}

Я пытался выполнить отладку с помощью расширения «Инструмент разработчика Redux». Я нашел в корзине 2 товара. (это правильное поведение)

Но когда я пытаюсь распечатать на консоли (в cart.js я пытался распечатать), я не вижу в корзине 2 товара.

Где я делаю ошибку?

Наблюдение:

Если бы я перенаправился на страницу «/cart» сразу после нажатия кнопки Кнопка «Добавить в корзину» (с помощью тега «Ссылка»), после чего я вижу элемент в тележка.
Но если я перенаправлю на страницу «/cart» отдельно, то появляется вышеуказанная проблема.

Обновление :
Приложение.js

import "./App.css";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import {
  About,
  Cart,
  Checkout,
  Error,
  HomeLayout,
  Landing,
  Login,
  Orders,
  Products,
  Register,
  SingleProduct,
} from "./pages";

const router = createBrowserRouter([
  {
    path: "/",
    element: <HomeLayout />,
    errorElement: <Error />,
    children: [
      {
        index: true,
        element: <Landing />,
      },
      {
        path: "products",
        element: <Products />,
      },
      {
        path: "products/:id",
        element: <SingleProduct />,
      },
      {
        path: "cart",
        element: <Cart />,
      },
      {
        path: "about",
        element: <About />,
      },
      {
        path: "checkout",
        element: <Checkout />,
      },
      {
        path: "orders",
        element: <Orders />,
      },
    ],
  },
  {
    path: "/login",
    element: <Login />,
    errorElement: <Error />,
  },
  {
    path: "/register",
    element: <Register />,
    errorElement: <Error />,
  },
]);
function App() {
  return <RouterProvider router = {router} />;
}

export default App;

Еще одно обновление: Навбар.jsx

import React, { useEffect, useState } from "react";
import { BsSunFill, BsMoonFill, BsCart3 } from "react-icons/bs";
import { FaBarsStaggered } from "react-icons/fa6";
import { NavLink } from "react-router-dom";
import { NavLinks } from "./NavLinks";
import { useSelector } from "react-redux";

function Navbar() {
  const items = useSelector((state) => state);
  return (
    <nav className = "navbar navbar-expand-sm  navbar-clr">
      <div className = "container">
        <NavLink
          to = "/"
          className = " navbar-brand btn btn-sm fs-6 d-none d-md-block text-white fs-6"
          style = {{ background: "#016efe" }}
        >
          C
        </NavLink>
        <button
          class = "navbar-toggler"
          type = "button"
          data-bs-toggle = "collapse"
          data-bs-target = "#navbarNav"
          aria-controls = "navbarNav"
          aria-expanded = "false"
          aria-label = "Toggle navigation"
        >
          <span class = "navbar-toggler-icon">
            <FaBarsStaggered className = "text-white" />
          </span>
        </button>

        <div class = "collapse navbar-collapse" id = "navbarNav">
          <ul class = "navbar-nav mx-auto ">
            <li class = "nav-item">
              <a
                class = "nav-link active text-black  mx-3"
                aria-current = "page"
                href = "/"
              >
                Home
              </a>
            </li>
            <li class = "nav-item">
              <a class = "nav-link text-black mx-3" href = "about">
                About
              </a>
            </li>
            <li class = "nav-item">
              <a class = "nav-link text-black mx-3" href = "product">
                Product
              </a>
            </li>
            <li class = "nav-item">
              <a
                class = "nav-link text-black mx-3 "
                // style = {{ background: "#02152c" }}
                href = "/cart"
              >
                Cart
              </a>
            </li>
            <li class = "nav-item">
              <a class = "nav-link text-black mx-3" href = "checkout">
                Checkout
              </a>
            </li>
            <li class = "nav-item">
              <a class = "nav-link text-black mx-3" href = "orders">
                Orders
              </a>
            </li>
          </ul>
          {/* <NavLinks /> */}
        </div>

        <NavLink to = "/cart" class = "position-relative">
          <div>
            <BsCart3
              style = {{ height: "30px", width: "30px" }}
              className = "text-black"
            />
            <span
              class = "position-absolute top-5 start-90 translate-middle badge rounded-pill"
              style = {{ background: "#016efe" }}
            >
              {items.cart1.length}
            </span>
          </div>
        </NavLink>
      </div>
    </nav>
  );
}

export default Navbar;

🤔 А знаете ли вы, что...
JavaScript обеспечивает обработку ошибок с использованием конструкции try...catch.


66
2

Ответы:

Если вы перенаправляете на страницу корзины с обновлением, вам следует использовать redux-persist для хранения этих данных на локальном компьютере пользователя, и если вы не получаете данные во время console.infoging, попробуйте добавить эту строку в свой cartSlice.js

export const cartSelector = state => state.Cart;

и во-вторых, измените корзину1 на Корзину в Store.js. Всегда сохраняйте одно и то же имя в своем store.js и имя фрагмента, например Cart и Cart, а не Cart и Cart1.

импортируйте свой cartSelector в Cart.js;

let cartItem = useSelector(cartSelector);

Я надеюсь, что это поможет вам.


Решено

Компонент Navbar отображает необработанные теги привязки, при нажатии на которые страница перезагружается, а все состояние, включая хранилище Redux, сбрасывается при перезагрузке страницы и перемонтировании приложения.

Вместо необработанных тегов привязки используйте компонент(ы) Link или NavLink из react-router-dom.

Пример:

import React, { useEffect, useState } from "react";
import { BsSunFill, BsMoonFill, BsCart3 } from "react-icons/bs";
import { FaBarsStaggered } from "react-icons/fa6";
import { NavLink } from "react-router-dom";
import { NavLinks } from "./NavLinks";
import { useSelector } from "react-redux";

function Navbar() {
  const items = useSelector((state) => state);
  return (
    <nav className = "navbar navbar-expand-sm  navbar-clr">
      <div className = "container">
        <NavLink
          to = "/"
          className = " navbar-brand btn btn-sm fs-6 d-none d-md-block text-white fs-6"
          style = {{ background: "#016efe" }}
        >
          C
        </NavLink>
        <button
          class = "navbar-toggler"
          type = "button"
          data-bs-toggle = "collapse"
          data-bs-target = "#navbarNav"
          aria-controls = "navbarNav"
          aria-expanded = "false"
          aria-label = "Toggle navigation"
        >
          <span class = "navbar-toggler-icon">
            <FaBarsStaggered className = "text-white" />
          </span>
        </button>

        <div class = "collapse navbar-collapse" id = "navbarNav">
          <ul class = "navbar-nav mx-auto ">
            <li class = "nav-item">
              <NavLink
                className = "nav-link active text-black  mx-3"
                aria-current = "page"
                to = "/"
              >
                Home
              </NavLink>
            </li>
            <li class = "nav-item">
              <NavLink className = "nav-link text-black mx-3" to = "/about">
                About
              </NavLink>
            </li>
            <li class = "nav-item">
              <NavLink className = "nav-link text-black mx-3" to = "/product">
                Product
              </NavLink>
            </li>
            <li class = "nav-item">
              <NavLink
                className = "nav-link text-black mx-3 "
                // style = {{ background: "#02152c" }}
                to = "/cart"
              >
                Cart
              </NavLink>
            </li>
            <li class = "nav-item">
              <NavLink className = "nav-link text-black mx-3" to = "/checkout">
                Checkout
              </NavLink>
            </li>
            <li class = "nav-item">
              <NavLink className = "nav-link text-black mx-3" to = "/orders">
                Orders
              </NavLink>
            </li>
          </ul>
        </div>

        <NavLink to = "/cart" class = "position-relative">
          <div>
            <BsCart3
              style = {{ height: "30px", width: "30px" }}
              className = "text-black"
            />
            <span
              class = "position-absolute top-5 start-90 translate-middle badge rounded-pill"
              style = {{ background: "#016efe" }}
            >
              {items.cart1.length}
            </span>
          </div>
        </NavLink>
      </div>
    </nav>
  );
}