React购物车组件报错Cannot read property 'length' of undefined求解
错误根因
你在App组件中给cart设置的初始值为空对象{},而fetchCart属于异步请求,首次渲染组件时请求还未返回结果,此时传入Cart组件的cart不存在line_items属性,访问cart.line_items.length自然会抛出读取undefined属性的错误。
可行解决方案(选任意一种即可,推荐方案2兼容性和通用性更强)
方案1:给cart状态预设初始结构
修改App.js中的cart初始值,提前声明需要用到的属性结构,避免属性不存在的问题:
// 把原来的 const [cart, setCart] = useState({}); 替换为 const [cart, setCart] = useState({ line_items: [], subtotal: {}, total_items: 0 });
方案2:在Cart组件中使用可选链规避空值报错
修改Cart组件中所有读取cart属性的代码,用可选链操作符?.处理属性可能不存在的情况:
// 把报错行替换为 const isEmpty = !cart?.line_items?.length; // 同时修改其他用到cart深层属性的位置 // 比如map遍历处改为 {cart.line_items?.map((item) => ( <Grid item xs={12} sm={4} key={item.id}> <div>{item.name}</div> </Grid> ))} // 小计显示处改为 Subtotal: {cart.subtotal?.formatted_with_symbol || '¥0.00'}
方案3:新增加载状态,请求完成后再渲染组件
在App中新增loading状态,等异步请求全部完成后再渲染Cart组件,从根源上避免空值传入:
const App = () => { const [products, setProducts] = useState([]); const [cart, setCart] = useState({}); const [loading, setLoading] = useState(true); const fetchProducts = async () => { const { data } = await commerce.products.list(); setProducts(data); }; const fetchCart = async () => { setCart(await commerce.cart.retrieve()); }; useEffect(() => { Promise.all([fetchProducts(), fetchCart()]).then(() => { setLoading(false); }) }, []); if(loading) return <div>加载中...</div> // 后续return逻辑不变 }
额外注意
你当前App.js的第一行import拼写错误,写为了mport,需要补全为import否则会触发编译错误。
内容的提问来源于stack exchange,提问作者tm616
相关产品推荐
相关产品推荐

