React TypeError:无法读取undefined的SOLDOUT属性问题排查
报错根因
- 变量类型和赋值逻辑混乱:你手动初始化
productsData为空数组[],数组不存在SOLDOUT、AVAILABLE自定义属性,首次渲染时直接读取这两个属性就会触发Cannot read properties of undefined报错,和setTimeout逻辑无关。 - 数据链路断裂:你从Redux中解构出了接口返回的
data,但后续判断、渲染逻辑完全没有使用这个变量,一直操作自己定义的空数组productsData,即使接口请求成功,数据也没有被用到页面渲染中。 - 时序逻辑不可靠:用setTimeout做10ms延时本质是赌接口在10ms内返回、Redux状态完成更新,完全没有兜底逻辑。把setTimeout写在useEffect外部时,函数组件每次重渲染都会重复触发定时器和接口请求,状态更新时序完全混乱,才会出现50次运行仅1次成功的情况。
- 加载态判断失效:判断加载状态时
productsData还是空数组,productsData['SOLDOUT'] === ""的条件永远不会成立,Loader组件根本不会按预期渲染。
稳定实现方案
核心逻辑是移除所有setTimeout延时,组件挂载时直接触发接口请求,通过判断Redux中接口数据的存在性控制加载态,数据返回完成后再渲染商品统计内容,从根源上避免时序问题。
修改后的完整代码如下:
const Allproducts = (props) => { useEffect(() => { // 组件挂载直接拉取数据,无任何延时 props.getProducts(); // 空依赖数组保证仅在组件首次挂载时执行一次请求 }, []); const { data } = props.security; // 接口数据未返回时,直接渲染加载组件 if (!data || data.AVAILABLE === undefined || data.SOLDOUT === undefined) { return <Loader />; } return( <div> <div> <h1 className="primary-header">Products</h1> <Broadcast/> </div> <Row> <Col> <Jumbotron id="allcards"> <div className="card"> <h2>{data.AVAILABLE}</h2> <h6>Available</h6> </div> </Jumbotron> </Col> <Col> <Jumbotron id="allcards"> <div className="card"> <h2>{data.SOLDOUT}</h2> <h6>Sold out</h6> </div> </Jumbotron> </Col> </Row> </div> ) } const mapStateToProps = (state) => ({ security: state.security, }); export default connect(mapStateToProps, { getProducts })(Allproducts);
关键修改点说明
- 移除useEffect中的setTimeout逻辑,直接调用
props.getProducts(),空依赖数组保证请求仅触发一次,不会重复调用。 - 删除无意义的
productsData中间变量,直接使用Redux返回的data做渲染,打通数据链路。 - 调整加载态判断逻辑:只要接口数据
data不存在,或者需要的两个统计字段未返回,就渲染Loader,从根源上避免读取undefined属性的报错。 - 不需要人为加任何延时,接口请求完成后Redux状态更新会自动触发组件重渲染,拿到最新数据渲染页面,逻辑完全可控,不受网络波动影响。
内容的提问来源于stack exchange,提问作者user8210845
相关产品推荐
相关产品推荐

