React提交修改商品价格表单后刷新页面出现报错如何解决

问题原因
- 核心问题是异步请求的时序问题:App组件中
productsData初始值为空数组,接口请求是异步执行的,刷新页面直接进入商品详情路由时,接口还未返回数据,products为空,products.find()返回undefined,后续直接访问listProduct.title、listProduct.image等属性就会触发报错。从商品列表页跳转进入详情不会报错的原因是跳转时接口已经请求完成,productsData有完整数据。 - 次要问题是价格持久化逻辑错误:当前localStorage只存了price字段,没有绑定对应商品ID,多个商品修改价格会互相覆盖,且App组件重新拉取接口数据时没有读取本地存储的修改后价格,刷新后修改的价格会重置为接口原始值。
修复方案
1. 解决访问undefined属性的报错
在ProductsDetails组件的render方法最前面加非空判断,数据未加载完成时显示加载提示:
render() { const { match: { params: { id } }, products } = this.props; const listProduct = products.find((product) => product.id === Number(id)); // 新增非空判断 if (!listProduct) { return <div>数据加载中,请稍候...</div> } // 原有渲染逻辑保持不变 }
2. 修复价格持久化逻辑
2.1 修改价格存储逻辑,按商品ID存储
修改ProductsDetails组件的submitHandler方法:
submitHandler = (e) => { e.preventDefault(); const id = this.state.id; // 按商品ID作为key存储价格,避免不同商品互相覆盖 localStorage.setItem(`price_${id}`, this.state.price); this.props.updatePrice(id, this.state.price); };
2.2 组件挂载时读取对应商品的存储价格
修改ProductsDetails组件的componentDidMount方法:
componentDidMount() { const id = this.state.id; const savedPrice = localStorage.getItem(`price_${id}`); if (savedPrice) { this.setState({price: savedPrice}); } }
2.3 接口拉取数据时同步本地存储的价格
修改App组件的useEffect逻辑,拉取接口数据后先合并本地修改过的价格:
useEffect(() => { axios.get("https://fakestoreapi.com/products?limit=7").then((res) => { // 合并本地存储的修改价格 const processedData = res.data.map(product => { const savedPrice = localStorage.getItem(`price_${product.id}`); return savedPrice ? {...product, price: Number(savedPrice)} : product; }) setProductsData(processedData); }); }, []);
内容的提问来源于stack exchange,提问作者RitalCharmant
相关产品推荐
相关产品推荐

