React:如何等待Prop数据加载完成后再渲染子组件
问题根源分析
- 父组件初始化
opportunityTable为空数组,但异步请求返回的是对象(结构为{data: {listMockOppsTables: 数据列表}}),类型不匹配。 - 子组件直接访问
this.props.data.data,初始时this.props.data是数组,数组没有data属性,导致this.props.data.data为undefined,调用map触发报错。 - 你之前的条件判断
this.props.data == undefined无效,因为初始状态是空数组而非undefined,判断不触发,直接执行渲染逻辑。
解决方案
方案1:统一状态类型+条件渲染
父组件修改
将状态初始值改为null,与后续赋值的对象类型统一:
// 替换原useState初始化代码 const [opportunityTable, changeOpportunityTable] = useState(null);
子组件修改
先判断数据是否加载完成,同时提取实际要遍历的列表,添加加载提示:
render() { // 用可选链安全获取数据,空值合并默认返回空数组 const opportunities = this.props.data?.data?.listMockOppsTables || []; // 数据未加载完成时显示加载提示 if (!this.props.data) { return <div>加载中...</div>; } return ( <div> <div className="row row-cols-1 row-cols-md-2 mx-auto" style={{ maxWidth: 900 }} > {/* 遍历列表必须加唯一key */} {opportunities.map((opportunity) => ( <div key={opportunity.id} className="col mb-4"> <div> <a href="#"> <img className="rounded img-fluid shadow w-100 fit-cover" src="assets/img/products/awsLogo.jpg" style={{ height: 250 }} /> </a> <div className="py-4"> <span className="badge mb-2" style={{ margin: 2, backgroundColor: "#ff9900" }} > {opportunity.interview_type} </span> <span className="badge bg mb-2" style={{ margin: 2, backgroundColor: "#ff9900" }} > 4 </span> <span className="badge bg mb-2" style={{ margin: 2, backgroundColor: "#ff9900" }} > Reverse </span> </div> </div> </div> ))} </div> </div> ); }
方案2:可选链+空值合并简化判断
如果不想修改父组件状态初始化,直接在子组件用可选链操作符避免报错:
render() { const opportunities = this.props.data?.data?.listMockOppsTables || []; return ( <div> <div className="row row-cols-1 row-cols-md-2 mx-auto" style={{ maxWidth: 900 }} > {opportunities.map((opportunity) => ( <div key={opportunity.id} className="col mb-4"> {/* 原渲染内容不变 */} </div> ))} </div> </div> ); }
额外优化建议
- 遍历列表时必须添加
key属性,使用每个条目的唯一标识(如opportunity.id),避免React警告。 - 父组件可简化异步逻辑,无需单独抽离
asyncCall函数:
useEffect(() => { const fetchData = async () => { const response = await API.graphql({ query: queries.listMockOppsTables, }); changeOpportunityTable(response); }; fetchData(); }, []);
内容的提问来源于stack exchange,提问作者Salman Djingueinabaye
相关产品推荐
相关产品推荐

