如何将API异步请求数据作为prop传递给React组件并解决相关报错?
问题原因
- 加载状态逻辑完全颠倒:
useLoadRecordshook中loading初始值设为了false,组件首次渲染时直接跳过加载态执行业务渲染逻辑,此时异步请求还未返回,数据还未完成赋值;且你是请求结束后才把loading设为false,和正常的加载状态逻辑完全相反。 - 使用了未定义的变量:组件代码中直接判断
recordGames.length,但你从hook中仅返回了records和loading两个值,从未声明过recordGames变量,未定义变量的异常会导致React渲染出错。 - 判断逻辑冗余混乱:嵌套了两层不必要的长度判断,一会校验
recordGames一会校验records,逻辑冲突。
修复代码
第一步:调整useLoadRecords hook逻辑
// useLoadRecords.js import { useState, useEffect } from 'react' import { API } from 'aws-amplify' import { listRecordGames } from '../graphql/queries' const useLoadRecords = () => { // 初始化加载状态为true,组件挂载即发起请求 const [loading, setLoading] = useState(true) const [records, updateRecords] = useState([]) useEffect(() => { fetchGames() }, []) const fetchGames = async () => { try { let recordData = await API.graphql({ query: listRecordGames, }) let records = recordData.data.listRecordGames.items.map( (item) => item.name ) let result = Object.values( records.reduce((acc, el) => { if (!acc[el]) acc[el] = { name: el, plays: 0 } acc[el].plays++ return acc }, {}) ) updateRecords(result) } catch (err) { console.error(err) } finally { // 无论请求成功失败,最后统一关闭加载状态 setLoading(false) } } return { records, loading } } export default useLoadRecords
第二步:简化GameDistribution组件逻辑
import useLoadRecords from '../../hooks/useLoadRecords' import { CustomPieChart } from '../charts/CustomPieChart' export const GameDistribution = () => { const { records, loading } = useLoadRecords() // 加载状态优先返回加载提示 if (loading) { return <span>Loading...</span> } return ( <div> {records.length > 0 ? ( <CustomPieChart data={records} /> ) : ( <div>No games</div> )} </div> ) }
内容的提问来源于stack exchange,提问作者Tyler Morales
相关产品推荐
相关产品推荐

