React useContext传递异步API数据遇.map()报错,求解决方案
解决React中useContext传递异步请求结果时的Promise问题
问题根源
异步函数SearchForTracks因async关键字,调用后会返回Promise对象,你直接将这个Promise传给setArtists,导致artists状态变成Promise而非预期的数组。子组件拿到Promise后调用.map()自然报错——Promise没有该方法。
同时你的代码还有两处小问题:
- API请求URL拼写错误:
searcq应为search?q=,否则请求会失败 onChangeHandler中[event.target.name] = event.target.value;是无效代码,逻辑错误且无实际作用
修复步骤及修正代码
1. 修正异步请求函数SearchForTracks
import axios from "axios"; export const SearchForTracks = async (entValue, tokens) =>{ // 修正URL拼写错误 const response = await axios.get(`https://api.spotify.com/v1/search?q=${entValue}&type=artist`, { headers:{ 'Authorization': `Bearer ${tokens}` } }) return response.data.artists.items }
2. 修正TopSearch组件的状态更新逻辑
必须用await等待异步请求完成,拿到实际数组后再更新状态:
import { createContext, useState, useContext } from 'react'; import { SearchForTracks } from './your-file-path'; // 替换为实际文件路径 export const ArtistContext = createContext(); function TopSearch() { const [open, setOpen] = useState(false); const [tokens] = useContext(TokenContext); const [artists, setArtists] = useState([]); const onChangeHandler = async(event) =>{ const entValue = event.target.value; // 等待异步请求返回数组结果 const fetchedArtists = await SearchForTracks(entValue, tokens); setArtists(fetchedArtists); } return ( <> <ArtistContext.Provider value={artists}> {open && <SearchLanding />} </ArtistContext.Provider> </> ); } export default TopSearch;
额外优化建议
可以添加加载状态提升用户体验:
// 在TopSearch组件中新增状态 const [isLoading, setIsLoading] = useState(false); const onChangeHandler = async(event) =>{ const entValue = event.target.value; setIsLoading(true); try { const fetchedArtists = await SearchForTracks(entValue, tokens); setArtists(fetchedArtists); } catch (error) { console.error('搜索失败:', error); // 可添加错误提示逻辑 } finally { setIsLoading(false); } }
子组件中可根据isLoading显示加载动画或提示,避免用户等待时无反馈。
内容的提问来源于stack exchange,提问作者ahmad sha'rbafinejad
相关产品推荐
相关产品推荐

