React调用Coinranking API报读取undefined的total属性错误
React项目Coinranking接口调用报错修复
问题表现
- 运行时抛出错误:
TypeError: Cannot read properties of undefined (reading 'total') - 复现路径:项目使用coinranking API获取加密货币数据,最初本地运行正常,部署托管后首次触发报错,后续本地环境也可稳定复现
- 报错位置:Homepage组件中访问
globalStats.total等属性时触发
根因分析
问题出在接口状态判断逻辑存在漏洞:
现有代码仅判断了isFetching(请求拉取中)状态就直接渲染业务内容,但RTK Query的请求流程除了拉取中状态,还存在请求失败、返回数据结构不符合预期的场景。当API返回异常(比如密钥失效、请求限流、跨域拦截、接口版本变更)时,isFetching会变为false,但此时data值为undefined,const globalStats = data?.data?.stats的赋值结果就是undefined,后续直接访问globalStats.total就会触发类型错误。
部署后首次触发问题,大概率是生产环境触发了coinranking的域名白名单校验、请求限流规则,或生产环境跨域配置异常,导致接口未返回预期的stats字段数据。
修复步骤
1. 补全请求状态兜底判断
从hook中导出error状态,在拉取完成后增加错误和数据存在性校验,避免非法数据进入渲染流程:
const Homepage = () => { // 新增导出error状态 const { data, isFetching, error } = useGetCryptosQuery(10); const globalStats = data?.data?.stats; if (isFetching) return <Loader />; // 新增错误、空数据判断 if (error || !globalStats) return <div>加密货币数据加载失败,请刷新重试</div>; // 原有渲染逻辑保持不变 return ( <> <Title level={2} className="heading">Global Crypto Stats</Title> <Row gutter={[32, 32]}> <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col> <Col span={12}><Statistic title="Total Exchanges" value={millify(globalStats.totalExchanges)} /></Col> <Col span={12}><Statistic title="Total Market Cap:" value={`$${millify(globalStats.totalMarketCap)}`} /></Col> <Col span={12}><Statistic title="Total 24h Volume" value={`$${millify(globalStats.total24hVolume)}`} /></Col> <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col> <Col span={12}><Statistic title="Total Markets" value={millify(globalStats.totalMarkets)} /></Col> </Row> <div className="home-heading-container"> <Title level={2} className="home-title">Top 10 Cryptos In The World</Title> <Title level={3} className="show-more"><Link to="/cryptocurrencies">Show more</Link></Title> </div> <Cryptocurrencies simplified /> <div className="home-heading-container"> <Title level={2} className="home-title">Latest Crypto News</Title> <Title level={3}><Link to="/news">Show more</Link></Title> </div> <News simplified /> </> ); };
2. (可选)属性访问增加可选链防护
如果需要更高的容错性,避免单个字段缺失导致页面崩溃,可以给属性访问增加可选链和默认值:
<Row gutter={[32, 32]}> <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats?.total || 0} /></Col> <Col span={12}><Statistic title="Total Exchanges" value={millify(globalStats?.totalExchanges || 0)} /></Col> <Col span={12}><Statistic title="Total Market Cap:" value={`$${millify(globalStats?.totalMarketCap || 0)}`} /></Col> <Col span={12}><Statistic title="Total 24h Volume" value={`$${millify(globalStats?.total24hVolume || 0)}`} /></Col> <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats?.total || 0} /></Col> <Col span={12}><Statistic title="Total Markets" value={millify(globalStats?.totalMarkets || 0)} /></Col> </Row>
3. 排查接口异常根因
完成上述兜底后页面不会再整页崩溃,可进一步排查接口返回异常的具体原因,常见触发点:
- coinranking API密钥配置错误,生产环境域名未添加到API白名单
- 请求频率过高触发coinranking限流规则
- 生产环境跨域配置错误,请求被浏览器拦截
- coinranking接口版本更新,返回数据结构发生变化,stats字段路径调整
内容的提问来源于stack exchange,提问作者Raynan Wuyep
相关产品推荐
相关产品推荐

