如何在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;
报错原因分析
- Context 导入错误:调用页面中使用默认导入
import ProductContext from '../context/ProductContext',但实际在Context文件中,ProductContext是命名导出的,默认导出的是ProductContextProvider。这会导致useContext获取到错误的对象,进而product为undefined,调用map时触发报错。 - 异步请求的状态更新问题:
setProduct是异步操作,在then中直接console.log(product)打印的是更新前的旧值,无法反映最新状态。 - 请求失败处理缺失:未处理
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
相关产品推荐
相关产品推荐

