You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Redux Toolkit+localStorage加入购物车功能失效排查

问题排查:Redux Toolkit购物车功能失效(无控制台输出)

我正在为电商网站使用Redux Toolkit开发加入购物车功能,搭配localStorage和Thunk中间件,但功能无法正常运行,控制台无任何输出,以下是相关代码,请帮忙排查问题:

CartSlice.js代码

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

const cartItemsFromStorage = localStorage.getItem("cartItems")
  ? JSON.parse(localStorage.getItem("cartItems"))
  : [];

const initialState = {
  cartItems: cartItemsFromStorage,
};

export const cartSlice = createSlice({
  name: "cartPage",
  initialState,
  reducers: {
    addItem(state, action) {
      const item = action.payload;
      const existItem = state.cartItems.find((x) => x.product === item.product);
      if (existItem) {
        return {
          ...state,
          cartItems: state.cartItems.map((x) =>
            x.product === existItem.product ? item : x
          ),
        };
      } else {
        return {
          ...state,
          cartItems: [...state.cartItems, item],
        };
      }
    },
  },
});

export const { addItem } = cartSlice.actions;
export default cartSlice.reducer;

export function addToCart(id, qty) {
  return async function addToCartThunk(dispatch, getState) {
    try {
      const { data } = await axios.get(`/api/products/${id}`);

      dispatch(
        addItem({
          product: data._id,
          name: data.name,
          image: data.image,
          price: data.price,
          countInStock: data.countInStock,
          qty,
        })
      );
      localStorage.setItem("cartItems", JSON.stringify(getState.cart));
    } catch (error) {
      console.log(error);
    }
  };
}

Store.js代码

import { configureStore } from "@reduxjs/toolkit";
import productReducer from "./productSlice";
import productDetailReducer from "./productDetailSlice";
import cartReducer from "./cartSlice";

const store = configureStore({
  reducer: {
    productList: productReducer,
    productDetails: productDetailReducer,
    cartPage: cartReducer,
  },
});

export default store;

CartScreen.js代码

import React from "react";
import { Link } from "react-router-dom";
import { useEffect } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { addToCart } from "../store/cartSlice";

const EMPTY_CART = { cartItems: [] };

const CartScreen = () => {
  const { productId } = useParams();

  const location = useLocation();
  const qty = location.search ? Number(location.search.split("=")[1]) : 1;
  const dispatch = useDispatch();

  const cart = useSelector((state) => state.cart || EMPTY_CART);
  const { cartItems } = cart;
  console.log(cartItems);

  useEffect(() => {
    if (productId) {
      dispatch(addToCart(productId, qty));
    }
  }, [dispatch, productId, qty]);

  return <div>Cart Page</div>;
};

export default CartScreen;

问题排查结果

1. useSelector 取值路径错误

在CartScreen.js中,useSelector尝试读取state.cart,但在Store.js里,cart reducer对应的键是cartPage,正确的取值应该是state.cartPage。当前代码因为取到undefined,所以使用了EMPTY_CART,导致cartItems始终为空数组,控制台输出空值。

修复代码:

// CartScreen.js
const cart = useSelector((state) => state.cartPage || EMPTY_CART);

2. localStorage 存储时的 getState 使用错误

在CartSlice.js的addToCartThunk中,getState是一个函数,需要调用它才能获取当前状态,并且要对应store里的cartPage键。当前代码getState.cart是错误的,会存储undefined到localStorage,导致下次读取时初始状态为空。

修复代码:

// CartSlice.js
localStorage.setItem("cartItems", JSON.stringify(getState().cartPage.cartItems));

(建议直接存储cartItems数组,而非整个cart对象,减少冗余)

3. 可选优化:Redux Toolkit reducer写法

Redux Toolkit内置Immer,可以直接修改state而无需返回新对象,addItem reducer可以简化写法(不影响功能,但更符合RTK规范):

addItem(state, action) {
  const item = action.payload;
  const existItem = state.cartItems.find((x) => x.product === item.product);
  if (existItem) {
    // 直接替换已有商品
    const index = state.cartItems.findIndex(x => x.product === existItem.product);
    state.cartItems[index] = item;
  } else {
    // 直接添加新商品
    state.cartItems.push(item);
  }
}

4. 额外检查点

  • 确认/api/products/${id}接口能正常返回数据,可在浏览器直接访问该URL测试
  • 检查是否存在跨域问题,若接口跨域需配置代理或CORS
  • 打开Redux DevTools查看是否有addItem action被触发,以及state是否更新

内容的提问来源于stack exchange,提问作者B GPT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:05:24