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

如何在React Context中存储并访问product数组?报错求助

React Context 获取产品列表复用时报错问题

问题情况

创建了包含fetch()的React Context用于从服务器获取产品列表,意图在页面中复用该数组,但控制台出现报错。以下是相关代码:

Context 代码

import React, { createContext, useState, useEffect } from 'react'
export const ProductContext = createContext()
const ProductContextProvider = (props) => {
    const [product, setProduct] = useState([]);
    const fetchData = () => {
        fetch(`http://localhost:8080/product`)
            .then((response) => response.json())
            .then((actualData) => {
                setProduct(actualData)
                console.log(product);
            })
    };
    useEffect(() => {
        fetchData();
    }, [])
    return (
        <ProductContext.Provider
            value={{ product }}>
            {props.children}
        </ProductContext.Provider>
    )
}
export default ProductContextProvider

调用页面代码

import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useContext } from 'react'
import ProductContext from '../context/ProductContext';
function Product() {
    const { product } = useContext(ProductContext)

    console.log(product);
    return (
        <div className="products-row ">
            {
                product.map((data, num) => {
                    return (
                        <div className="product" key={num}>
                            <div className="card">
                                <a target="_blank" href="/design" >
                                    <img src={data.thumbnail} alt={data.name} style={{ width: "100%" }} ></img>
                                </a>
                                <h1>{data.name}</h1>
                                <p className="price">${data.price}</p>
                            </div>
                        </div>
                    )
                })
            }
        </div>
    );
}

export default Product;

报错原因分析

  1. Context 导入错误:调用页面中使用默认导入import ProductContext from '../context/ProductContext',但实际在Context文件中,ProductContext是命名导出的,默认导出的是ProductContextProvider。这会导致useContext获取到错误的对象,进而product为undefined,调用map时触发报错。
  2. 异步请求的状态更新问题:setProduct是异步操作,在then中直接console.log(product)打印的是更新前的旧值,无法反映最新状态。
  3. 请求失败处理缺失:未处理fetch请求失败的情况(比如服务器错误、网络问题),若请求失败或JSON解析出错,会直接抛出错误导致状态未更新,甚至引发页面异常。

解决方案

1. 修正Context导入方式

在调用页面中,改为命名导入ProductContext:

import { ProductContext } from '../context/ProductContext';

2. 完善请求错误处理

在fetch中添加catch块处理请求或解析错误,确保product始终保持数组类型:

const fetchData = () => {
    fetch(`http://localhost:8080/product`)
        .then((response) => {
            if (!response.ok) {
                throw new Error('请求失败');
            }
            return response.json();
        })
        .then((actualData) => {
            setProduct(actualData);
        })
        .catch((error) => {
            console.error('获取产品数据失败:', error);
            setProduct([]);
        });
};

3. 正确查看更新后的状态

如果需要查看product更新后的值,添加useEffect监听状态变化:

useEffect(() => {
    console.log('更新后的产品数据:', product);
}, [product]);

4. 可选:添加加载状态

为提升用户体验,可在Context中添加加载状态,避免请求未完成时页面出现异常:

const [product, setProduct] = useState([]);
const [loading, setLoading] = useState(true);

const fetchData = () => {
    fetch(`http://localhost:8080/product`)
        .then((response) => {
            if (!response.ok) throw new Error('请求失败');
            return response.json();
        })
        .then((actualData) => {
            setProduct(actualData);
        })
        .catch((error) => {
            console.error('获取数据失败:', error);
            setProduct([]);
        })
        .finally(() => {
            setLoading(false);
        });
};

然后在Provider的value中加入loading,在调用页面中判断加载状态:

const { product, loading } = useContext(ProductContext);

if (loading) {
    return <div>加载中...</div>;
}

内容的提问来源于stack exchange,提问作者Joel John Noronha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:35:29