React父子组件传值异常:父组件GraphQL数据无法在子组件展示
问题分析与修复方案
父组件(Dashboard)核心问题
- state初始化错误:直接将异步函数
asyncCall()传入useState,导致opportunityTable存储的是Promise对象,而非请求返回的实际数据。 - API配置重复执行:
API.configure(config)放在组件内部,每次组件渲染都会重复执行,应移到组件外部确保只执行一次。 - 异步请求处理不当:未通过
useEffect触发异步请求,也未将请求结果正确更新到state中。 - 数据提取不完整:GraphQL返回结构为
gqlreturn.data.listMockOppsTables.items,需提取数组数据再传递给子组件。
子组件(DashboardTable)核心问题
- 构造函数未接收props:
constructor()未传入props参数,super()也未传递props,导致this.props无法获取父组件数据。 - 错误存储props到state:将整个
this.props存入opportunityData,实际需要的是this.props.data;且props更新时state不会自动同步,无需将props存入state,直接使用即可。 - 未处理加载/空数据状态:数据未返回时直接调用
map会报错,需添加状态判断。 - 变量访问错误:
render中使用this.opportunityData,但数据实际存储路径错误(即使修复后也无需存入state)。
修复后的父组件代码
import React, { useEffect, useState } from "react"; import "bootstrap/js/src/collapse.js"; import DashboardTable from "../DashboardTable"; import { API } from "@aws-amplify/api"; import config from "../../aws-exports"; import * as queries from "../../graphql/queries"; // API配置移到组件外部,仅执行一次 API.configure(config); export default function Dashboard() { const [opportunityTable, changeOpportunityTable] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchData() { try { const gqlreturn = await API.graphql({ query: queries.listMockOppsTables, }); // 提取实际数组数据 changeOpportunityTable(gqlreturn.data.listMockOppsTables.items); } catch (error) { console.error("数据请求失败:", error); } finally { setLoading(false); } } fetchData(); }, []); // 空依赖数组,仅组件挂载时执行一次 return ( <div> <section className="py-5 mt-5"> <div className="container py-5"> <h2 className="fw-bold text-center"> Your upcoming shadowing events <br /> <br /> </h2> {/* 处理加载状态 */} {loading ? ( <div className="text-center">加载中...</div> ) : ( <DashboardTable data={opportunityTable} /> )} </div> </section> </div> ); }
修复后的子组件代码
import React from "react"; import "bootstrap/js/src/collapse.js"; import Navigation from "../Navigation"; import { Link } from "react-router-dom"; export class DashboardTable extends React.Component { render() { const { data } = this.props; // 处理空数据情况 if (!data || data.length === 0) { return <div className="text-center">暂无数据</div>; } return ( <div> <div className="row row-cols-1 row-cols-md-2 mx-auto" style={{ maxWidth: 900 }} > {data.map((opportunity, index) => ( {/* 添加key避免React警告 */} <div className="col mb-4" key={index}> <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 mb-2" style={{ margin: 2, backgroundColor: "#ff9900" }} > {opportunity.level} </span> <span className="badge mb-2" style={{ margin: 2, backgroundColor: "#ff9900" }} > {opportunity.ShadowReverse} </span> </div> </div> </div> ))} </div> </div> ); } } export default DashboardTable;
内容的提问来源于stack exchange,提问作者Salman Djingueinabaye
相关产品推荐
相关产品推荐

