React中GraphQL数据无法传递至子组件的问题排查
问题排查与修复方案
一、Dashboard组件的核心问题及修复
1. 异步数据未通过React状态管理,组件无法自动更新
你用普通变量存储异步请求结果,但React函数组件必须通过useState管理状态,数据更新时才会触发组件重新渲染,将最新数据传递给子组件。同时异步函数内部重新声明变量,导致外层变量始终为undefined。
2. 异步请求时机错误,未处理初始状态
直接在组件顶层调用异步函数会导致重复请求,需用useEffect包裹并设置空依赖数组确保仅执行一次。初始状态下直接访问opportunityTable.data会报错,需做可选链或初始值处理。
3. Props传递名称不匹配
Dashboard传递的props是data,但Table组件试图读取props.items,名称完全不对应。
修复后的Dashboard.js:
import React, { useState, useEffect } 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"; export default function Dashboard() { const [opportunityData, setOpportunityData] = useState([]); API.configure(config); useEffect(() => { async function fetchData() { try { const response = await API.graphql({ query: queries.listMockOppsTables, }); // 根据实际返回结构调整,此处假设数据在items数组中 setOpportunityData(response.data.listMockOppsTables.items || []); } catch (err) { console.error("数据获取失败:", err); } } fetchData(); }, []); return ( <div> <div className="container py-5"> <DashboardTable items={opportunityData} /> </div> </div> ); }
二、Table组件(Opportunity)的核心问题及修复
1. 状态与Props引用错误
你在constructor中将props.items存入state,但render时直接调用this.opportunityData,正确应为this.state.opportunityData。此外无需将props存入state,直接使用this.props.items更稳妥。
2. DOM结构错误
将<tbody>放在map循环内会导致每行tr都包裹独立tbody,不符合HTML规范,应将<tbody>放在循环外,仅渲染一次。
3. React语法错误:class需改为className
React元素的类名必须用className,原生class会导致样式不生效且触发警告。
4. 未处理空数据情况
数据加载中或为空时调用map会报错,需先判断数据是否存在且非空。
修复后的Opportunity组件:
import React from "react"; import "bootstrap/js/src/collapse.js"; export class Opportunity extends React.Component { render() { const { items } = this.props; console.log("接收的数据:", items); if (!items || items.length === 0) { return <div className="py-5 text-center">暂无数据</div>; } return ( <div> <section className="py-5 mt-5"> <div className="container py-5"> <div className="table-responsive"> <table className="table"> <thead> <tr> <th>Shadow ID</th> <th>Role Title</th> <th>Interview Type</th> <th>Level</th> <th>Date and Time</th> <th># Requests</th> <th>Make Request</th> </tr> </thead> <tbody> {items.map((opportunity) => ( <tr key={opportunity.shadow_id}> {/* 使用数据唯一ID作为key */} <td>{opportunity.shadow_id}</td> <td>{opportunity.job_title}</td> <td>{opportunity.shadow_type}</td> <td>4</td> <td> {opportunity.shadow_datetime} <br /> {opportunity.shadow_datetime} </td> <td>2</td> <td> <div className="btn-group" role="group"> <button className="btn btn-primary" type="button" style={{ backgroundColor: "#ff9900", border: 0, }} > Shadow </button> <button className="btn btn-primary" type="button" style={{ backgroundColor: "#ffac2f", border: 0, }} > Reverse Shadow </button> </div> </td> </tr> ))} </tbody> </table> </div> </div> </section> </div> ); } } export default Opportunity;
三、额外注意事项
- 确认GraphQL返回的数据结构与代码中访问的路径一致,若实际结构不同需对应调整。
- 循环渲染时优先使用数据中的唯一标识作为
key,避免React渲染优化异常。 - 保留错误捕获逻辑,防止API请求失败导致组件崩溃。
内容的提问来源于stack exchange,提问作者Salman Djingueinabaye
相关产品推荐
相关产品推荐

