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

Next.js 13中添加"use client"后出现React子元素渲染错误求助

错误原因

Next.js 13的服务器组件支持直接用async/await获取数据并渲染,因为服务器端预渲染时会等待Promise resolve后再生成HTML。但当你给组件加上"use client"后,组件变成客户端组件——客户端组件的渲染逻辑在浏览器中执行,React无法直接渲染async组件函数返回的Promise对象,这就是你看到Error: Objects are not valid as a React child (found: [object Promise])的根本原因。

解决方法

方案1:分离数据获取与交互逻辑(最优解)

保留服务器组件负责数据获取,只把需要交互的部分抽成独立的客户端组件,通过props传递数据:

  1. 服务器组件(负责数据获取,无需"use client")
// app/[classe]/page.jsx
async function fetchClassData(classeName) {
  const res = await fetch(`https://www.dnd5eapi.co/api/classes/${classeName}`);
  return res.json();
}

export default async function ClassPage({ params }) {
  const classData = await fetchClassData(params.classe);
  return (
    <div>
      <h1>{classData.name}</h1>
      {/* 将数据传给客户端交互组件 */}
      <InteractiveSkillList skills={classData.skills} />
    </div>
  );
}
  1. 客户端组件(负责交互,加"use client")
// app/components/InteractiveSkillList.jsx
"use client";

export default function InteractiveSkillList({ skills }) {
  const handleSkillClick = (desc) => {
    // 这里写你的点击交互逻辑,比如弹窗展示详情
    alert(desc);
  };

  return (
    <ul>
      {skills.map((skill) => (
        <li 
          key={skill.index} 
          onClick={() => handleSkillClick(skill.desc)}
          style={{ cursor: 'pointer', color: '#0070f3' }}
        >
          {skill.name}
        </li>
      ))}
    </ul>
  );
}

方案2:在客户端组件内获取数据

如果必须在客户端组件中获取数据,不能直接用async组件函数,要结合useState+useEffect或者数据获取库(如SWR、React Query)处理异步逻辑:

用useState+useEffect实现
"use client";

import { useState, useEffect } from 'react';

export default function ClientSideSkillList() {
  const [skills, setSkills] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchSkills = async () => {
      const res = await fetch('https://www.dnd5eapi.co/api/skills');
      const data = await res.json();
      setSkills(data.results);
      setLoading(false);
    };
    fetchSkills();
  }, []);

  if (loading) return <div>加载中...</div>;

  return (
    <ul>
      {skills.map((skill) => (
        <li 
          key={skill.index} 
          onClick={() => console.log(skill.desc)}
          style={{ cursor: 'pointer' }}
        >
          {skill.name}
        </li>
      ))}
    </ul>
  );
}
用SWR实现(Next.js推荐的客户端数据获取方案)
"use client";

import useSWR from 'swr';

// 通用请求函数
const fetcher = async (url) => {
  const res = await fetch(url);
  return res.json();
};

export default function SWRBasedSkillList() {
  const { data, error, isLoading } = useSWR('https://www.dnd5eapi.co/api/skills', fetcher);

  if (error) return <div>加载技能失败</div>;
  if (isLoading) return <div>加载中...</div>;

  return (
    <ul>
      {data.results.map((skill) => (
        <li 
          key={skill.index} 
          onClick={() => console.log(skill.desc)}
          style={{ cursor: 'pointer' }}
        >
          {skill.name}
        </li>
      ))}
    </ul>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:43:13