React项目遇Uncaught TypeError: data?.map is not a function报错求助
问题:React中调用map函数时报错
data?.map is not a function 背景
刚接触React,开发音乐APP,跟着教程编码但使用了不同的API,页面仅显示白色背景,控制台持续报错:
Uncaught TypeError: data?.map is not a function
代码
import React from 'react'; import { Error, Loader, SongCard } from '../components'; import { genres } from '../assets/constants'; import { useGetTopChartsQuery } from '../redux/services/shazamApi'; const Discover = () => { const { data, isFetching, error } = useGetTopChartsQuery(); const genreTitle = 'Pop'; console.log(data); return( <div className="flex flex-col"> <div className="w-full flex justify-between items-center sm:flex-row flex-col mt-4 mb-10"> <h2 className="font-bold text-3xl text-white text-left">Discover {genreTitle}</h2> <select onChange={() => {}} value="" className='bg-black text-gray-300 p-3 text-sm rounded-lg outline-none sm:mt-0 mt-5' > {genres.map((genre) => <option key={genre.value} value={genre.value}>{genre.title}</option>)} </select> </div> <div className="flex flex-wrap sm:justify-start justify-center gap-8"> {data?.map((song, i) => ( <SongCard key={song.key} song={song} data={data} i={i} /> ))} </div> </div> ); }; export default Discover;
API返回数据结构
{ "properties": {}, "tracks": [ { "layout": "5", "type": "MUSIC", "key": "673557639", "title": "Paint The Town Red", "subtitle": "Doja Cat", "share": { "subject": "Paint The Town Red - Doja Cat", "text": "Paint The Town Red by Doja Cat", "href": "https://www.shazam.com/track/673557639/paint-the-town-red", "image": "https://is1-ssl.mzstatic.com/image/thumb/Music116/v4/97/c7/f2/97c7f256-6db0-a45b-a786-f58dc928c970/196871404495.jpg/400x400cc.jpg", "twitter": "I used @Shazam to discover Paint The Town Red by Doja Cat.", "html": "https://www.shazam.com/snippets/email-share/673557639?lang=en-US&country=US", "avatar": "https://is4-ssl.mzstatic.com/image/thumb/AMCArtistImages116/v4/54/ba/99/54ba9945-5aae-bec7-a80c-188de630b37b/d62857dc-e8bd-41f6-b4d5-e368875c6044_ami-identity-7d4c30a95a90f129a834aecd444aa07a-2023-06-16T14-02-41.627Z_cropped.png/800x800cc.jpg", "snapchat": "https://www.shazam.com/partner/sc/track/673557639" }, "images": { "background": "https://is4-ssl.mzstatic.com/image/thumb/AMCArtistImages116/v4/54/ba/99/54ba9945-5aae-bec7-a80c-188de630b37b/d62857dc-e8bd-41f6-b4d5-e368875c6044_ami-identity-7d4c30a95a90f129a834aecd444aa07a-2023-06-16T14-02-41.627Z_cropped.png/800x800cc.jpg", "coverart": "https://is1-ssl.mzstatic.com/image/thumb/Music116/v4/97/c7/f2/97c7f256-6db0-a45b-a786-f58dc928c970/196871404495.jpg/400x400cc.jpg", "coverarthq": "https://is1-ssl.mzstatic.com/image/thumb/Music116/v4/97/c7/f2/97c7f256-6db0-a45b-a786-f58dc928c970/196871404495.jpg/400x400cc.jpg", "joecolor": "b:ffffffp:050607s:1b1515t:373838q:494443" }, "hub": { "type": "APPLEMUSIC", "image": "https://images.shazam.com/static/icons/hub/web/v5/applemusic.png", "actions": [ { "name": "apple", "type": "applemusicplay", "id": "1704921697" }, { "name": "apple", "type": "uri", "uri": "https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview116/v4/cd/87/0b/cd870b5f-c356-f761-e176-c45aba37eab1/mzaf_17565732451070337798.plus.aac.ep.m4a" } ], "options": [ { "caption": "OPEN", "actions": [ { "name": "hub:applemusic:deeplink", "type": "applemusicopen", "uri": "https://music.apple.com/us/album/paint-the-town-red/1704921687?i=1704921697&mttnagencyid=s2n&mttnsiteid=125115&mttn3pid=Apple-Shazam&mttnsub1=Shazam_web&mttnsub2=5348615A-616D-3235-3830-44754D6D5973&itscg=30201&app=music&itsct=Shazam_web" }, { "name": "hub:applemusic:deeplink", "type": "uri", "uri": "https://music.apple.com/us/album/paint-the-town-red/1704921687?i=1704921697&mttnagencyid=s2n&mttnsiteid=125115&mttn3pid=Apple-Shazam&mttnsub1=Shazam_web&mttnsub2=5348615A-616D-3235-3830-44754D6D5973&itscg=30201&app=music&itsct=Shazam_web" } ], "beacondata": { "type": "open", "providername": "applemusic" }, "image": "https://images.shazam.com/static/icons/hub/web/v5/overflow-open-option.png", "type": "open", "listcaption": "Open in Apple Music", "overflowimage": "https://images.shazam.com/static/icons/hub/web/v5/applemusic-overflow.png", "colouroverflowimage": false, "providername": "applemusic" } ], "explicit": true, "displayname": "APPLE MUSIC" }, "artists": [ { "alias": "doja-cat", "id": "42", "adamid": "830588310" } ], "url": "https://www.shazam.com/track/673557639/paint-the-town-red", "highlightsurls": { "artisthighlightsurl": "https://cdn.shazam.com/video/v3/en-US/US/web/830588310/highlights?affiliate=mttnagencyid=s2n&mttnsiteid=125115&mttn3pid=Apple-Shazam&mttnsub1=Shazam_web&mttnsub2=5348615A-616D-3235-3830-44754D6D5973&itscg=30201&app=music&itsct=Shazam_web&videoIdToFilter=1701008023", "trackhighlighturl": "https://cdn.shazam.com/video/v3/en-US/US/web/highlights/1701008023?affiliate=mttnagencyid=s2n&mttnsiteid=125115&mttn3pid=Apple-Shazam&mttnsub1=Shazam_web&mttnsub2=5348615A-616D-3235-3830-44754D6D5973&itscg=30201&app=music&itsct=Shazam_web" }, "properties": {} } ] }
报错信息
Uncaught TypeError: data?.map is not a function at Discover (Discover.jsx:27:20) at renderWithHooks (react-dom.development.js:16305:18) at updateFunctionComponent (react-dom.development.js:19588:20) at beginWork (react-dom.development.js:21601:16) at beginWork$1 (react-dom.development.js:27426:14) at performUnitOfWork (react-dom.development.js:26557:12) at workLoopSync (react-dom.development.js:26466:5) at renderRootSync (react-dom.development.js:26434:7) at recoverFromConcurrentError (react-dom.development.js:25850:20) at performSyncWorkOnRoot (react-dom.development.js:26096:20)
解决方案
错误原因
map方法仅能用于数组,而你从API获取的data是一个对象,并非数组。歌曲列表实际存储在data.tracks这个数组属性里,直接对data调用map自然会触发报错。
修改代码
将data?.map改为data?.tracks?.map,同时建议添加加载状态和错误状态的处理,优化页面体验:
import React from 'react'; import { Error, Loader, SongCard } from '../components'; import { genres } from '../assets/constants'; import { useGetTopChartsQuery } from '../redux/services/shazamApi'; const Discover = () => { const { data, isFetching, error } = useGetTopChartsQuery(); const genreTitle = 'Pop'; // 加载中显示Loader组件 if (isFetching) return <Loader />; // 出错显示Error组件 if (error) return <Error />; return( <div className="flex flex-col"> <div className="w-full flex justify-between items-center sm:flex-row flex-col mt-4 mb-10"> <h2 className="font-bold text-3xl text-white text-left">Discover {genreTitle}</h2> <select onChange={() => {}} value="" className='bg-black text-gray-300 p-3 text-sm rounded-lg outline-none sm:mt-0 mt-5' > {genres.map((genre) => <option key={genre.value} value={genre.value}>{genre.title}</option>)} </select> </div> <div className="flex flex-wrap sm:justify-start justify-center gap-8"> {/* 改为遍历data.tracks数组 */} {data?.tracks?.map((song, i) => ( <SongCard key={song.key} song={song} data={data} i={i} /> ))} </div> </div> ); }; export default Discover;
额外建议
- 更换API后务必确认返回的数据结构,重点关注数据层级是否和教程一致
- 利用可选链操作符
?.避免空值报错,同时结合加载、错误状态处理,让页面状态更清晰
内容的提问来源于stack exchange,提问作者Dzeminie
相关产品推荐
相关产品推荐

