React项目中使用RapidAPI加载加密货币数据,刷新页面丢失数据并触发TypeError问题求助
解决React中使用RapidAPI加载加密货币数据时的刷新报错问题
咱们来一步步拆解你遇到的问题:
为什么会抛出TypeError: Cannot read properties of undefined (reading 'name')?
这是组件渲染和API请求的时序冲突导致的:
- 你初始化
coinData为一个空数组[],页面刷新后组件首次渲染时,coinData[0]是undefined,此时直接访问coinData[0].name自然会触发报错。 useEffect里的API请求是在组件挂载后才发起的,数据返回需要一定时间,但组件在数据返回前就已经完成了首次渲染,所以触发了这个错误。
为什么刷新页面后需要重新加载数据?
这是React单页应用的正常行为:页面刷新后,整个应用会重新初始化,组件会重新挂载,useEffect的空依赖数组[]会在组件挂载时再次执行API请求,所以数据会重新加载。如果想避免每次刷新都重新请求,可以考虑用本地存储做缓存(后面会提到)。
解决方案
1. 使用可选链操作符(最简洁的方法)
在访问name的时候添加可选链?.,这样当coinData[0]为undefined时,表达式会返回undefined而不是抛出错误,还可以搭配默认值提升用户体验:
<h1>Discover {coinData[0]?.name || '热门加密货币交易所'}</h1>
2. 条件渲染(更灵活的控制)
在渲染依赖coinData的内容前,先判断数据是否已加载完成,还可以添加加载提示:
return ( <div className="homepage"> {coinData.length > 0 ? ( <> <div className="heading"> <h1>Discover {coinData[0].name}</h1> <hr className="line" /> </div> <div className="cards-container"> <CryptoCard /> </div> </> ) : ( <div className="loading">加载中...</div> )} </div> );
3. 本地存储缓存数据(解决刷新重新加载的需求)
如果想让刷新页面后保留之前的数据,可以把获取到的数据存在localStorage里,组件初始化时先读取缓存:
const Homepage = () => { // 初始化时优先读取本地缓存 const [coinData, setCoinData] = useState(() => { const cachedData = localStorage.getItem('exchangeData'); return cachedData ? JSON.parse(cachedData) : []; }); useEffect(() => { const options = { method: "GET", url: "https://coinranking1.p.rapidapi.com/exchanges", headers: { "x-rapidapi-host": "coinranking1.p.rapidapi.com", "x-rapidapi-key": "REDACTED", }, }; axios .request(options) .then((response) => { const exchanges = response.data.data.exchanges; setCoinData(exchanges); // 把数据存入本地缓存 localStorage.setItem('exchangeData', JSON.stringify(exchanges)); }) .catch((error) => { console.error(error); }); }, []); // 渲染部分搭配可选链避免报错 return ( <div className="homepage"> <div className="heading"> <h1>Discover {coinData[0]?.name || '加载中...'}</h1> <hr className="line" /> </div> <div className="cards-container"> <CryptoCard /> </div> </div> ); };
内容的提问来源于stack exchange,提问作者Husnain Mehmood
相关产品推荐
相关产品推荐

