React中Map遍历Fetch数据报错:bitData.map is not a function
问题排查:React调用CoinDesk API后无法遍历数据报错
作为React应用开发初学者,调用CoinDesk的API获取数据后,无法遍历返回的JSON数据,执行map函数时出现错误:Uncaught TypeError: bitData.map is not a function,相关代码及错误栈信息如下:
代码示例
//import logo from './logo.svg'; import './App.css'; import {useEffect, useState} from 'react'; function App() { const[bitData, setbitData]=useState([]); useEffect(()=>{ fetch("https://api.coindesk.com/v1/bpi/currentprice.json",{ method:'GET' }).then(result=>result.json()) .then(result=>setbitData(result)) },[]) return ( <div className="App"> { bitData && <table className="table"> <thead> <tr> <th scope="col">Code</th> <th scope="col">Symbol</th> <th scope="col">Rate</th> <th scope="col">Description</th> <th scope="col">Rate_float</th> </tr> </thead> <tbody> { bitData.map(draw=> <tr> <th scope="row">{draw.code}</th> <td>{draw.symbol}</td> <td>{draw.rate}</td> <td>{draw.description}</td> </tr> )} </tbody> </table> } </div> ); } export default App;
错误栈信息
Uncaught TypeError: bitData.map is not a function at App (App.js:28:1) at renderWithHooks (react-dom.development.js:16305:1) at updateFunctionComponent (react-dom.development.js:19588:1) at beginWork (react-dom.development.js:21601:1) at beginWork$1 (react-dom.development.js:27426:1) at performUnitOfWork (react-dom.development.js:26557:1) at workLoopSync (react-dom.development.js:26466:1) at renderRootSync (react-dom.development.js:26434:1) at recoverFromConcurrentError (react-dom.development.js:25850:1) at performConcurrentWorkOnRoot (react-dom.development.js:25750:1) App @ App.js:28 renderWithHooks @ react-dom.development.js:16305 updateFunctionComponent @ react-dom.development.js:19588 beginWork @ react-dom.development.js:21601 beginWork$1 @ react-dom.development.js:27426 performUnitOfWork @ react-dom.development.js:26557 workLoopSync @ react-dom.development.js:26466 renderRootSync @ react-dom.development.js:26434 recoverFromConcurrentError @ react-dom.development.js:25850 performConcurrentWorkOnRoot @ react-dom.development.js:25750 workLoop @ scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533
问题原因及解决方法
问题根源
CoinDesk API返回的是一个对象,而非数组。直接将整个返回对象赋值给bitData后,调用数组专属的map方法自然会报错。
查看API返回结构,实际需要的币种数据在返回对象的bpi字段中,该字段本身也是一个对象(包含USD、GBP、EUR等子对象),需要先将其转换为数组才能使用map遍历。
修正步骤
- 在获取API数据后,提取
result.bpi,并使用Object.values()将其转换为数组; - 保持初始状态为数组,确保组件渲染时不会因为类型不匹配报错。
修正后的代码
//import logo from './logo.svg'; import './App.css'; import {useEffect, useState} from 'react'; function App() { const[bitData, setbitData]=useState([]); useEffect(()=>{ fetch("https://api.coindesk.com/v1/bpi/currentprice.json",{ method:'GET' }).then(result=>result.json()) // 提取bpi字段并转换为数组 .then(result=>setbitData(Object.values(result.bpi))) },[]) return ( <div className="App"> { bitData.length > 0 && <table className="table"> <thead> <tr> <th scope="col">Code</th> <th scope="col">Symbol</th> <th scope="col">Rate</th> <th scope="col">Description</th> <th scope="col">Rate_float</th> </tr> </thead> <tbody> { bitData.map(draw=> <tr key={draw.code}> {/* 添加key属性,符合React列表渲染规范 */} <th scope="row">{draw.code}</th> <td>{draw.symbol}</td> <td>{draw.rate}</td> <td>{draw.description}</td> <td>{draw.rate_float}</td> {/* 补充Rate_float列的内容 */} </tr> )} </tbody> </table> } </div> ); } export default App;
额外优化:
- 添加
key属性到列表项,符合React列表渲染的性能优化规范; - 将判断条件从
bitData &&改为bitData.length > 0,更准确判断数组是否有数据; - 补充了
Rate_float列的内容,对应表头字段。
内容的提问来源于stack exchange,提问作者Desai Vibha
相关产品推荐
相关产品推荐

