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

无法通过传入ID获取localStorage中产品的问题求助

问题:无法通过ID获取localStorage中的产品

当前流程:在ProductDetails组件中通过dispatch传递ID到productsSlice,切片调用productsService.getProductById(),该方法与async-storage-service交互,但无法获取对应产品,控制台无报错。

代码问题分析及修复方案

1. Redux切片无法处理异步操作

productsSlice中的getProduct reducer是同步函数,但调用的productsService.getProductById()是异步方法,reducers不能直接处理异步逻辑,需要改用createAsyncThunk。

修复后的productsSlice.js:

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import productsService from './products-service';

// 定义异步action
export const getProduct = createAsyncThunk(
  'products/getProduct',
  async (productId, { rejectWithValue }) => {
    try {
      return await productsService.getProductById(productId);
    } catch (error) {
      return rejectWithValue(error.message);
    }
  }
);

const initialState = {
  product: null,
  loading: false,
  error: null
};

const productsSlice = createSlice({
  name: 'products',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(getProduct.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(getProduct.fulfilled, (state, action) => {
        state.loading = false;
        state.product = action.payload;
      })
      .addCase(getProduct.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  }
});

export default productsSlice.reducer;

2. ID类型不匹配导致查找失败

useParams()获取的id是字符串类型,但localStorage中存储的产品id是数字类型,===严格比较会匹配失败。

修复后的async-storage-service.js中的get方法:

function get(entityType, entityId) {
  // 将传入的entityId转为数字,匹配存储的产品id类型
  const numId = Number(entityId);
  return query(entityType)
    .then(entities => entities.find(entity => entity.id === numId));
}

3. ProductDetails组件未正确订阅Redux状态且存在无限循环

  • useEffect依赖项包含product,会导致组件更新时重复触发dispatch,造成无限循环。
  • 组件使用本地useState存储产品,未从Redux状态中获取数据。

修复后的ProductDetails.jsx:

import { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getProduct } from './productsSlice';
import { useParams } from 'react-router-dom';

export function ProductDetails() {
  const dispatch = useDispatch();
  const { id } = useParams();
  // 从Redux获取产品、加载状态和错误
  const { product, loading, error } = useSelector(state => state.products);

  useEffect(() => {
    if (id) {
      dispatch(getProduct(id));
    }
  }, [id, dispatch]); // 移除product依赖,避免无限循环

  if (loading) return <div>加载中...</div>;
  if (error) return <div>获取产品失败:{error}</div>;
  if (!product) return <div>未找到产品</div>;

  return (
    <div>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
      {/* 其他产品信息 */}
    </div>
  );
}

4. 确保localStorage中已存在产品数据

确认products-service.js中的query方法已经执行过,将产品数据存入localStorage。如果首次加载时localStorage为空,可以在组件初始化时先调用query方法:

// 在ProductDetails的useEffect中添加
useEffect(() => {
  // 先确保localStorage有数据
  productsService.query();
  if (id) {
    dispatch(getProduct(id));
  }
}, [id, dispatch]);

内容的提问来源于stack exchange,提问作者Amit Amar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:40:57