React获取后端产品数据时出现undefined问题排查与解决
问题:调用/get-all-products接口后数据undefined的解决
问题原因
- 未触发数据请求Action:原页面组件完全没有调用
getAllProducts这个Action,Redux的productReducer初始状态里没有allProducts字段,所以useSelector拿到的allProducts一直是undefined。 - 冗余本地state放大了undefined问题:原代码用本地
datastate同步Redux的allProducts,初始时allProducts是undefined,导致setData(undefined),后续渲染时data.map就会因为undefined报错。
完整解决方案
1. 页面组件核心修复
在组件中添加useDispatch触发数据请求,移除冗余本地state,直接基于Redux状态处理渲染和分类过滤:
import { useState, useEffect } from "react"; import styles from "../styles/styles"; import { useSearchParams } from "react-router-dom"; import { useSelector, useDispatch } from "react-redux"; import { getAllProducts } from "../actions/productAction"; import ProductCard from "../components/Route/productCard/ProductCard"; import Header from "../components/layout/Header"; import Loader from "../components/layout/Loader"; import Footer from "../components/layout/Footer"; const ProductsPage = () => { const [searchParams] = useSearchParams(); const categoryData = searchParams.get("category"); const { allProducts, isLoading } = useSelector((state) => state.products); const dispatch = useDispatch(); // 组件挂载时触发产品数据请求 useEffect(() => { dispatch(getAllProducts()); }, [dispatch]); // 直接基于Redux数据处理分类过滤 const filteredProducts = categoryData ? allProducts?.filter(i => i.category === categoryData) : allProducts; return ( <> {isLoading ? ( <Loader /> ) : ( <div> <Header activeHeading={3} /> <br /> <br /> <div className={`${styles.section}`}> <div className="grid grid-cols-1 gap-[20px] md:grid-cols-2 md:gap[25px] lg:grid-cols-4 lg:gap-[25px] xl:grid-cols-5 xl:gap-[30px] mb-12"> {filteredProducts?.map((i, index) => ( <ProductCard data={i} key={index} /> ))} </div> {filteredProducts?.length === 0 ? ( <h1 className="text-center w-full pb-[100px] text-[20px]"> 暂无产品! </h1> ) : null} </div> <Footer /> </div> )} </> ); }; export default ProductsPage;
2. 其他代码确认(无需修改)
- 后端接口:返回格式正确,
products字段包含查询到的产品数据 - Reducer:成功回调中正确设置
state.allProducts = action.payload - Action:正确获取接口返回的
data.products并dispatch到reducer - Store:正确将
productReducer注册到products命名空间
额外优化建议
在Reducer的初始状态中添加allProducts: [],避免初始时allProducts为undefined:
const initialState = { isLoading: true, allProducts: [], // 新增默认空数组 };
这样可以去掉代码中的可选链(?.),让逻辑更简洁。
内容的提问来源于stack exchange,提问作者Ahmed Khaled
相关产品推荐
相关产品推荐

