调用Deezer API获正确响应仍遇React [object Promise]渲染报错求助
解决React中"对象不能作为React子元素(发现:[object Promise])"报错
我调用Deezer API获取数据时,碰到了这个报错:
未捕获错误:对象不能作为React子元素(发现:[object Promise])。如果您想渲染子元素集合,请改用数组。
已经试过三种方案(代码如下),能拿到正确的响应数据(10条对象组成的数组),但报错依然存在,怀疑是tracks状态处理的问题,想知道问题根源。
解决方案1
import React, { useState, useEffect } from 'react'; import Layout from '../Layout.jsx'; import Playlists from '../components/others/Playlists'; import TrackListContainer from '../components/others/TrackListContainer'; import axios from 'axios'; const CORS_PROXY = 'https://api.allorigins.win/raw?url='; const DEEZER_API_URL = 'https://api.deezer.com/'; const api = axios.create({ baseURL: CORS_PROXY + DEEZER_API_URL, timeout: 15000, }); function LibraryPage() { const [tracks, setTracks] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { const response = await api.get('chart/0/tracks?limit=10'); const data = response.data.data; setTracks(data || []); } catch (error) { console.error('Error fetching data:', err); setError(err); } finally { setLoading(false); } }; fetchData(); }, []); if (loading) { return <div>Loading...</div>; } if (error) { return <div>Error fetching data</div>; } return ( <div className='home-container'> {Array.isArray(tracks) && tracks.length > 0 ? ( <TrackListContainer header='Trending right now' tracks={tracks} /> ) : ( <div>No tracks available.</div> )} <Playlists /> </div> ); }
解决方案2
const fetchData = () => { api .get('chart/0/tracks?limit=10') .then((response) => { const data = response.data.data; setTracks(Array.isArray(data) ? data : []); }) .catch((err) => { console.error('Error fetching data:', err); setError(err); }) .finally(() => { setLoading(false); }); };
解决方案3
class LibraryPage extends Component { constructor(props) { super(props); this.state = { tracks: [], loading: true, error: null, }; } async componentDidMount() { try { const response = api.get('chart/0/tracks?limit=10'); const data = response.data.data; console.log("this is the data", data); this.setState({ tracks: data, loading: false }); } catch (error) { console.error('Error fetching data:', error); this.setState({ error, loading: false }); } } render() { const { tracks, loading, error } = this.state; if (loading) { return <div>Loading...</div>; } if (error) { return <div>Error fetching data</div>; } return ( <div className='home-container'> {Array.isArray(tracks) && tracks.length > 0 ? ( <TrackListContainer header='Trending right now' tracks={tracks} /> ) : ( <div>No tracks available.</div> )} <Playlists /> </div> ); } }
问题根源分析
你能成功获取到正确的tracks数组,说明LibraryPage组件里的状态处理没问题,报错的核心原因不在当前页面的请求逻辑,而是某个子组件(大概率是TrackListContainer或Playlists)中直接渲染了Promise对象。
常见触发场景:
- 子组件的
render方法(或函数组件返回值)使用了async/await,导致返回Promise而非React元素 - 子组件处理tracks数据时,某个步骤返回Promise,却直接把这个Promise当成JSX元素渲染
- 子组件中存在未正确处理的异步操作,比如在JSX中直接调用异步函数而不处理返回值
另外补充代码细节问题:
- 解决方案3的
componentDidMount中,api.get前缺少await,会导致response是Promise对象,此时response.data.data会是undefined,但你说能拿到正确数据,说明实际运行的不是这个版本或已修正 - 解决方案1的catch块中,参数是
error但代码里用了err,会导致err未定义,不过这只会在报错时出现日志错误,不是当前Promise子元素报错的原因
排查建议
检查
TrackListContainer组件:看它接收tracks后,是否在渲染时把异步操作的结果(Promise)直接当成子元素返回,比如:// 错误示例:函数组件用async async function TrackItem({ track }) { const artist = await fetchArtist(track.artist.id); return <div>{artist.name}</div>; }这种情况会让组件返回Promise,触发报错。
检查
Playlists组件:同样排查是否存在直接渲染Promise的情况,比如在JSX中直接调用异步函数:// 错误示例:JSX中直接调用异步函数 return <div>{fetchPlaylists()}</div>;确认所有子组件的返回值都是React元素或数组,而非Promise对象。如果需要在子组件中做异步操作,应该用
useEffect(函数组件)或componentDidMount(类组件)处理,把结果存在状态中再渲染。
内容的提问来源于stack exchange,提问作者omnibusAdmin
相关产品推荐
相关产品推荐

