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

React渲染报错:[object Promise]不可作为合法React子节点

问题根因

React只允许渲染字符串、数字、JSX元素、数组、Fragment、布尔值/null/undefined这些合法子节点,不支持直接渲染Promise对象。
你在JSX中直接调用返回Promise的getBookings()方法时,表达式的求值结果就是Promise实例本身,即使你在.then()回调中返回了JSX结构,那也只是Promise异步resolve后的内部值,渲染同步执行阶段拿到的始终是Promise对象,因此触发报错。
除此之外你的写法还有一个严重问题:接口请求直接写在JSX渲染表达式里,组件每次重渲染都会重复触发接口调用,产生大量无效请求,极易引发数据不一致、页面卡顿问题。

修复方案

核心思路是分离数据请求和渲染逻辑:接口请求放在副作用钩子中执行,请求结果存入组件状态,渲染阶段直接读取状态值生成JSX即可。

  • 首先在组件内声明所需状态,存储当前行程的预订数据、加载状态
import { useState, useEffect } from 'react';

// 组件内部代码
const [rideBookings, setRideBookings] = useState([]);
const [isLoading, setIsLoading] = useState(false);
  • 将接口请求移入useEffect,配置正确的依赖项避免重复请求
useEffect(() => {
  // 未登录状态下跳过请求
  if (!currentUser.id) return;
  const loadBookings = async () => {
    setIsLoading(true);
    try {
      const bookingList = await getBookings(r.id);
      setRideBookings(bookingList);
    } catch (err) {
      console.error('获取预订信息失败:', err);
      setRideBookings([]);
    } finally {
      setIsLoading(false);
    }
  };
  loadBookings();
// 依赖项为行程id、当前用户id,值变化时才会重新触发请求
}, [r.id, currentUser.id]);
  • 修正JSX渲染逻辑,移除JSX中的直接Promise调用,基于已存在的状态渲染内容
{
  !currentUser.id ? '' : 
  isLoading ? <div>加载中...</div> :
  (() => {
    const filteredBookings = rideBookings.filter(b => parseInt(b.uid) === parseInt(currentUser.id));
    if (rideBookings.length > 0 && filteredBookings.length > 0) {
      return (
        <div className="d-flex justify-content-center align-items-center">
          <div className='contact-d'>
            <a href={`tel:${r.phone}`} className="btn rounded-pill border-0 py-3 mb-2 mb-md-0 mt-2 mt-md-0 calldriver mx-2">call</a>
            <Link to="/chat-booked" className="btn rounded-pill border-0 py-3 mb-2 mb-md-0 calldriver mx-2">Messag</Link>
            <a href="mailto:support@puchkoo.com" className="btn rounded-pill py-3 reportride mx-2">Report Ride</a>
          </div>
        </div>
      )
    }
    return '';
  })()
}

额外优化建议

你原来的getBookings函数手动嵌套了一层Promise包装属于冗余写法,fetch本身就返回Promise,可以简化为:

const getBookings = async (rid) => {
  const res = await fetch(`${process.env.REACT_APP_SERVER_URL}/bookings/${rid}`, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    }
  });
  const data = await res.json();
  if (data.error) throw new Error(data.message);
  setBookings(data.data);
  return data.data;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:12:29