无法通过传入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
相关产品推荐
相关产品推荐

