React调用CoinGecko API获取代币详情时重复访问报错问题
解决React代币详情页返回后重新进入的价格读取错误
问题根源
返回首页再进入同一代币详情页时,组件重新挂载但数据请求可能未及时触发,或者数据未加载完成就尝试读取嵌套属性,导致market_data为undefined,进而抛出Cannot read properties of undefined (reading 'current_price')错误。
具体解决方法
1. 确保useEffect正确触发API请求
详情页组件中,必须将路由参数(如代币ID)加入useEffect的依赖数组,保证每次进入页面(包括返回后重新进入)都会重新发起数据请求:
import { useParams } from 'react-router-dom'; import { useState, useEffect } from 'react'; const CoinDetail = () => { const { coinId } = useParams(); // 假设路由参数为coinId const [singleCoin, setSingleCoin] = useState(null); useEffect(() => { const fetchCoinDetail = async () => { try { const response = await fetch(`https://api.coingecko.com/api/v3/coins/${coinId}`); const data = await response.json(); setSingleCoin(data); } catch (error) { console.error('获取代币详情失败:', error); } }; fetchCoinDetail(); // 可选:用AbortController取消未完成请求,避免内存泄漏 const controller = new AbortController(); return () => controller.abort(); }, [coinId]); // 依赖路由参数,参数变化/组件重新挂载时触发 // 其他代码... };
2. 渲染前做数据校验+加载状态
在渲染价格等嵌套属性前,先判断singleCoin是否存在,避免在数据加载完成前访问undefined属性:
// 替换原价格渲染逻辑 if (!singleCoin) { return <div>加载中...</div>; } return ( <div className="coin-detail"> <h2>{singleCoin.symbol.toUpperCase()}</h2> <p>当前USD价格: ${singleCoin.market_data.current_price.usd}</p> </div> );
3. 使用可选链操作符做防御性访问
如果不想单独写加载判断,或者需要在数据加载时显示默认值,可以用可选链操作符(?.),即使中间属性为undefined也不会报错:
<p>当前USD价格: ${singleCoin?.market_data?.current_price?.usd || '加载中...'}</p>
4. 检查组件缓存问题
如果项目使用了路由缓存组件(如react-router-cache-route),返回再进入时组件可能不会重新挂载,导致useEffect未触发。这种情况需要:
- 禁用该详情页的缓存
- 或者监听路由变化手动触发请求:
import { useLocation } from 'react-router-dom'; // 在组件内添加 const location = useLocation(); useEffect(() => { fetchCoinDetail(); // 路由变化时重新请求 }, [location.pathname]);
内容的提问来源于stack exchange,提问作者Charly
相关产品推荐
相关产品推荐

