You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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子元素报错的原因

排查建议

  1. 检查TrackListContainer组件:看它接收tracks后,是否在渲染时把异步操作的结果(Promise)直接当成子元素返回,比如:

    // 错误示例:函数组件用async
    async function TrackItem({ track }) {
      const artist = await fetchArtist(track.artist.id);
      return <div>{artist.name}</div>;
    }
    

    这种情况会让组件返回Promise,触发报错。

  2. 检查Playlists组件:同样排查是否存在直接渲染Promise的情况,比如在JSX中直接调用异步函数:

    // 错误示例:JSX中直接调用异步函数
    return <div>{fetchPlaylists()}</div>;
    
  3. 确认所有子组件的返回值都是React元素或数组,而非Promise对象。如果需要在子组件中做异步操作,应该用useEffect(函数组件)或componentDidMount(类组件)处理,把结果存在状态中再渲染。

内容的提问来源于stack exchange,提问作者omnibusAdmin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:24:56