ReactJS项目中Modal弹窗表格数据为空问题求助
React项目Modal表格数据不显示问题排查
我正在开发一个ReactJS项目,通过Axios调用API获取数据并在Modal弹窗中展示。点击“E Score”按钮后Treemap图表能正常显示,但表格始终为空,尽管API已正确返回对应数据。以下是相关代码及问题截图:
const ChartSmallDoughnutChart3 = ({ aux, name, variable }) => { const { themeValues } = useSelector((state) => state.settings); const chartContainer = useRef(null); const legendRef = useRef(null); const [semiFullExample, setSemiFullExample] = useState(false); const [keywordsList, setKeywords] = useState(); const [detailsList, setDetails] = useState(); const couleur = 'rgb(75, 192, 192)'; function timeout(delay) { return new Promise((res) => setTimeout(res, delay)); } const getDetails = async () => { const queryResult = await axios.post(GRAPHQL_API, { query: GET_KEYWORDS_DETAILS, variables: { company: name, category: variable, }, }); const result = queryResult.data.data.getDetailsKeyword; setDetails(result); console.log(result); }; const handleModalLoad = async (param1, param2) => { const getKeywordsList = async () => { const queryResult = await axios.post(GRAPHQL_API, { query: GET_KEYWORDS_LIST, variables: { company: param1, category: param2, }, }); const result = queryResult.data.data.getKeywords; setKeywords(result); }; getKeywordsList(); setSemiFullExample(true); await timeout(1000); getDetails(); // setSemiFullExample(true); }; const CustomSmallLegendDoughnutPlugin = React.useMemo(() => { return { id: 'htmlLegendDoughnutSmall', afterUpdate: (chart, args, options) => { const items = chart.options.plugins.legend.labels.generateLabels(chart); ReactDOM.render( <> {items.map((legend) => { const { strokeStyle, text, index, hidden } = legend; return ( <div key={`customLegend${index}`}> <div className="text-small text-muted text">{text}</div> <Button variant="link" className="mb-1" onClick={() => handleModalLoad(name, variable)}> {' '} <div className="cta-3 text-info value">E Score</div> </Button> </div> ); })} </>, legendRef.current ); }, }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [name, variable]); return ( <> <Row className="g-0 d-flex w-100"> <Col ref={legendRef} className="sh-8 d-flex flex-column justify-content-center custom-legend-container" /> <Col xs="auto"> <canvas ref={chartContainer} className="sw-8 sh-8" /> </Col> </Row> <Modal show={semiFullExample} onHide={() => setSemiFullExample(false)} size="semi-full" scrollable centered> <Modal.Header closeButton> <Modal.Title>E Score Details</Modal.Title> </Modal.Header> <Modal.Body> <TreemapChart aux={keywordsList} color={couleur} /> <section className="scroll-section" id="stripedRows"> <> <h2 className="small-title">ESG Details</h2> <Table striped> <thead> <tr> <th scope="col">Paragraph</th> <th scope="col">Link</th> <th scope="col">Topic</th> <th scope="col">Keywords</th> <th scope="col">Key-Words</th> <th scope="col">Sentiment</th> <th scope="col">Sentiment Score</th> <th scope="col">Paraphrase</th> <th scope="col">Topic Score</th> </tr> </thead> <tbody> {detailsList?.map((item, i) => ( <tr key={i}> <td>{item.Paragraph}</td> <td>{item.Link}</td> <td>{item.Topic}</td> <td>{item.keywords}</td> <td>{item.key_words}</td> <td>{item.Sentiment}</td> <td>{item.Sentiment_Score}</td> <td>{item.Paraphrase}</td> <td>{item.Topic_Score}</td> </tr> ))} </tbody> </Table> </> </section> </Modal.Body> <Modal.Footer> <Button onClick={() => setSemiFullExample(false)}>Close</Button> </Modal.Footer> </Modal> </> ); };


问题排查与解决
字段名匹配问题
检查API返回的字段名与表格渲染时使用的字段是否完全一致。从截图看API返回的字段可能存在大小写或命名格式差异,比如确认Paragraph、Link等字段是否和接口返回的键名完全匹配,避免因字段名拼写错误导致数据无法渲染。异步逻辑顺序问题
当前代码用固定1秒延迟调用getDetails,这种方式不可靠,可能导致Modal打开时detailsList还未更新。修改handleModalLoad,确保数据请求完成后再打开Modal:const handleModalLoad = async (param1, param2) => { // 先获取keywordsList const keywordsRes = await axios.post(GRAPHQL_API, { query: GET_KEYWORDS_LIST, variables: { company: param1, category: param2 }, }); setKeywords(keywordsRes.data.data.getKeywords); // 再获取details数据 const detailsRes = await axios.post(GRAPHQL_API, { query: GET_KEYWORDS_DETAILS, variables: { company: name, category: variable }, }); setDetails(detailsRes.data.data.getDetailsKeyword); // 所有数据获取完成后打开Modal setSemiFullExample(true); };初始状态设置问题
detailsList初始值为undefined,虽然用了可选链?.map,但如果API返回空数组,表格仍会显示空白。将初始状态设为空数组:const [detailsList, setDetails] = useState([]);这样即使没有数据,表格也能显示表头和空行,更符合预期。
React状态更新异步性问题
状态更新是异步的,若Modal已打开但状态还未更新,可通过useEffect监听detailsList变化,确保组件能重新渲染。不过通常React会自动处理状态更新后的重渲染,但若存在复杂逻辑,可添加监听:useEffect(() => { if (semiFullExample && detailsList) { // 可添加额外的渲染逻辑 } }, [semiFullExample, detailsList]);
内容的提问来源于stack exchange,提问作者Mondher HADDAD
相关产品推荐
相关产品推荐

