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

React条件渲染展示接口数据时出现空白页及非法子节点报错

问题描述

在React中实现条件渲染逻辑:接口数据未拉取完成时展示"Loading"加载提示,数据拉取完成后展示服务端返回的JSON响应数据。实际运行时页面空白:将数据加载成功分支的渲染内容替换为纯文本时页面可正常展示,替换为接口返回的实际数据时触发异常,呈现空白页。

问题复现代码
import { useState, useEffect } from 'react'

function changeFeed(bookData){
   let elem;
   if (Object.keys(bookData).length === 0) elem = <p>Loading</p>
   else 
    elem = <p>{bookData}</p>

   return elem;
}

export default function Feed() {
   const [bookData, setBookData] = useState({});

   useEffect(() => {
     fetch('/book')
     .then(res => res.json())
     .then(data => setBookData(data))
     .catch(err => console.error("Custom err: ",err))
   }, []);

   return (
     <div>
      {changeFeed(bookData)}
     </div>
   )
}
运行报错信息

核心报错:

Uncaught Error: Objects are not valid as a React child (found: object with keys {data}). If you meant to render a collection of children, use an array instead.

完整错误栈:

Uncaught Error: Objects are not valid as a React child (found: object with keys {data}). If you meant to render a collection of children, use an array instead.
    at throwOnInvalidObjectType (react-dom.development.js:14757:1)
    at reconcileChildFibers (react-dom.development.js:15698:1)
    at reconcileChildren (react-dom.development.js:19971:1)
    at updateHostComponent$1 (react-dom.development.js:20733:1)
    at beginWork (react-dom.development.js:22447:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)
    at invokeGuardedCallback (react-dom.development.js:4274:1)
    at beginWork$1 (react-dom.development.js:27405:1)
    at performUnitOfWork (react-dom.development.js:26513:1)
react-dom.development.js:18572 The above error occurred in the <p> component:

    at p
    at div
    at Feed (http://localhost:3000/static/js/bundle.js:129:82)
    at div
    at http://localhost:3000/static/js/bundle.js:1449:66
    at Grid (http://localhost:3000/static/js/bundle.js:8640:87)
    at div
    at http://localhost:3000/static/js/bundle.js:1449:66
    at Grid (http://localhost:3000/static/js/bundle.js:8640:87)
    at div
    at http://localhost:3000/static/js/bundle.js:1449:66
    at Box (http://localhost:3000/static/js/bundle.js:19329:72)
    at Home
    at InnerThemeProvider (http://localhost:3000/static/js/bundle.js:18542:70)
    at ThemeProvider (http://localhost:3000/static/js/bundle.js:18199:5)
    at ThemeProvider (http://localhost:3000/static/js/bundle.js:18562:5)
    at App

Consider adding an error boundary to your tree to customize error handling behavior.
logCapturedError @ react-dom.development.js:18572
react-dom.development.js:26874 Uncaught Error: Objects are not valid as a React child (found: object with keys {data}). If you meant to render a collection of children, use an array instead.
    at throwOnInvalidObjectType (react-dom.development.js:14757:1)
    at reconcileChildFibers (react-dom.development.js:15698:1)
    at reconcileChildren (react-dom.development.js:19971:1)
    at updateHostComponent$1 (react-dom.development.js:20733:1)
    at beginWork (react-dom.development.js:22447:1)
    at beginWork$1 (react-dom.development.js:27381:1)
    at performUnitOfWork (react-dom.development.js:26513:1)
    at workLoopSync (react-dom.development.js:26422:1)
    at renderRootSync (react-dom.development.js:26390:1)
    at recoverFromConcurrentError (react-dom.development.js:25806:1)
manifest.json:1 Manifest: Line: 1, column:1, Syntax error.

注:末尾的manifest.json语法错误是项目PWA配置文件问题,和本次白屏的渲染错误无关

接口返回数据结构

接口返回书籍对象数组,示例结构:

[
  {_id: '628a333def2ed59e884896b2', title: 'everything need to be known', author_id: '6281de055717560ea372c656', summary: 'Summary need to be updated plz check after sometime', isbn: '69-ass-69'},
  {_id: '628a39263e2377b56cb55a28', title: 'everyhton needto knpe', author_id: '6281de055717560ea372c656', summary: 'Summary need to be updated plz check after sometime', isbn: '159'},
  {_id: '628a3a2a66c6bb5f9c8d39c3', title: 'jkejvnskre vkn', author_id: '6281de055717560ea372c656', summary: 'Summary need to be updated plz check after sometime', isbn: 'lkrmvle'},
  {_id: '628a3aa53de4e9fa6f4a6124', title: 'jcnj jflkl kK', author_id: '6281de055717560ea372c656', summary: 'Summary need to be updated plz check after sometime', isbn: 'lck lsdk'},
  {_id: '628a5bad4c97c8d9a5828dc7', title: 'avrj f,lskfjf', author_id: '6281de055717560ea372c656', summary: 'Summary need to be updated plz check after sometime', isbn: 'lkv skjf '},
  {_id: '628a5c4baa89e5d3a93f6398', title: 'k cjdkj,fk;klad', author_id: '6281de055717560ea372c656', summary: 'Summary need to be updated plz check after sometime', isbn: 'klc wjd'}
]
问题原因
  • 核心问题:React不支持直接将JavaScript对象、数组作为JSX子元素渲染,只能渲染字符串、数字、合法的React节点、布尔值/null/undefined(这些会被忽略)。代码里数据加载完成后直接把bookData(接口返回的对象/数组)放到<p>标签内,React无法将普通对象解析为DOM节点,直接抛出渲染异常导致整页白屏。
  • 加载判断逻辑有隐患:通过判断空对象的键长度来确认加载状态,一旦接口返回空数组、空对象,会一直停留在Loading状态;报错提示明确说明拿到的对象带data键,说明接口实际返回结构是{data: 书籍数组}的格式,直接赋值后bookData不是数组,后续遍历也会出问题。
修复方案
  • 单独维护loading状态标记加载过程,不要依赖数据是否为空判断加载状态,避免空数据场景的判断错误。
  • 接口返回数据先按实际结构取出需要渲染的数组部分,不要直接渲染整个响应对象。
  • 渲染数组时通过map遍历每一项,将对象的字段拆分为基础类型值(字符串、数字)渲染,不要直接输出整个对象。
  • 如果只是临时调试查看接口返回内容,可以用JSON.stringify(bookData)将对象转为字符串后渲染,不要直接放原始对象。

修复后的可运行代码:

import { useState, useEffect } from 'react'

export default function Feed() {
  const [bookData, setBookData] = useState([]);
  // 单独维护加载状态
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setLoading(true);
    fetch('/book')
      .then(res => res.json())
      .then(res => {
        // 兼容两种接口返回结构:直接返回数组 / 返回{data: 数组}格式
        setBookData(Array.isArray(res) ? res : res.data || [])
      })
      .catch(err => console.error("Custom err: ", err))
      .finally(() => setLoading(false))
  }, []);

  if (loading) return <p>Loading</p>

  return (
    <div>
      {bookData.map(book => (
        <div key={book._id} style={{ marginBottom: '1rem' }}>
          <h3>{book.title}</h3>
          <p>ISBN:{book.isbn}</p>
          <p>摘要:{book.summary}</p>
        </div>
      ))}
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:54:18