MERN栈应用中无法访问ProductContext内商品数据问题求助
问题根本原因
你在productData方法中使用window.location执行跳转,这会触发浏览器整页重载,所有React应用在内存中维护的状态(包括Context的存储值)都会被清空重置:
- 跳转前Context里的
product确实已经被接口返回值更新,所以你能在Context里打印到正确数据 - 整页刷新后
ProductContextProvider重新初始化,内部product状态回到初始值{},此时加载的ProductAbout组件自然拿不到之前存储的数据
修复方案
方案1:替换整页跳转为React Router的客户端跳转(改动最小,保留Context状态)
只要把window.location改为React Router提供的无刷新跳转方法即可:
- React Router v6版本修改Context代码:
import { useNavigate } from 'react-router-dom' const ProductContextProvider = (props) => { const [product, setProduct] = useState({}) const navigate = useNavigate() // 新增这行获取导航方法 const productData = (id) => { fetch (`${API}/products/details/${id}`, { method: 'GET', }) .then (response => response.json ()) .then (response => { setProduct(response) // 替换整页跳转为客户端无刷新跳转 navigate(`/details/${id}`) }) .catch (error => { console.error (error); }) } // 其余原有代码保持不变 }
- 如果是React Router v5版本,把
useNavigate替换为useHistory,调用history.push(/details/${id})即可。
方案2:详情页主动拉取数据(更稳定,支持直接访问/刷新详情页)
方案1仅能解决从商品列表点击跳转的场景,如果用户直接访问详情页地址、或者刷新详情页,Context还是没有数据,更稳妥的做法是让ProductAbout主动拉取数据:
import { useParams, useEffect } from 'react-router-dom' const ProductAbout = () => { const { id } = useParams() const [product, productData] = useContext(ProductContext) // 组件挂载时校验数据,不存在就主动拉取 useEffect(() => { if(!product?._id || product._id !== id) { productData(id) } }, [id, product, productData]) console.log(product) return( <div>hi{product?.name}</div> ) }
同时可以把Context中productData方法里的跳转逻辑移除,直接在Products组件的点击事件中执行客户端跳转即可。
内容的提问来源于stack exchange,提问作者Yollo
相关产品推荐
相关产品推荐

