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

ReactJS未知键名时渲染对象值报错的解决咨询

解决React渲染API数据时的"Objects are not valid as a React child"报错

问题背景

你在React中尝试渲染从SQL Server获取的数据时遇到报错:

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

同时需要在未知键名的前提下渲染数据,已提供前后端及数据库操作代码。

报错原因

  1. 后端返回数据格式错误:mssql库的query方法返回的allData是一个包含元数据的对象(比如recordset、rowsAffected等),而非单纯的查询结果数组。直接把这个完整对象返回给前端,导致前端状态存的不是可遍历的数据数组。
  2. 前端渲染逻辑错误:即使拿到正确的数据数组,直接把数组中的对象(每条数据库记录)放到<h2>标签里,React无法直接渲染对象类型的子元素。

解决方案

第一步:修正后端数据返回

修改数据库操作代码,返回真正的查询结果数组(即recordset属性):

// dbFiles/dbOperation.js
const config = require('./dbConfig');
const sql = require('mssql');

const getData = async() => {
    try{
        let pool = await sql.connect(config);
        let allData = await pool.request().query("SELECT * from Alerts");
        // 返回查询到的行数据数组
        return allData.recordset;
    }
    catch(error){
        console.log(error);
        // 错误时返回空数组,避免前端报错
        return [];
    }
}
module.exports = {
    getData
}

第二步:优化前端渲染逻辑

  1. 使用useEffect执行数据请求,避免组件每次渲染都重复调用fetchData
  2. 处理加载状态,避免初始空数据时的异常
  3. 遍历每条记录的键值对,渲染具体内容(适配未知键名的场景)

修改后的React代码:

import { useState, useEffect } from 'react';

function App() {
  const [returnedData, setReturnedData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  const fetchData = async () => {
    try {
      const res = await fetch("/api", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
      });
      const newData = await res.json();
      setReturnedData(newData);
    } catch (err) {
      console.error('数据请求失败:', err);
    } finally {
      setIsLoading(false);
    }
  };

  // 仅在组件挂载时执行一次请求
  useEffect(() => {
    fetchData();
  }, []);

  if (isLoading) {
    return <div>加载中...</div>;
  }

  return (
    <div className="data-container">
      {returnedData.length === 0 ? (
        <p>暂无数据</p>
      ) : (
        returnedData.map((record, recordIndex) => (
          <div key={recordIndex} className="record-item">
            {/* 遍历当前记录的所有键值对 */}
            {Object.entries(record).map(([key, value], index) => (
              <p key={index}>
                <strong>{key}:</strong> {String(value)}
              </p>
            ))}
            <hr />
          </div>
        ))
      )}
    </div>
  );
}

export default App;

代码说明

  • useEffect:确保数据请求只在组件首次挂载时执行一次,避免重复请求
  • isLoading:处理加载状态,提升用户体验
  • Object.entries(record):将每条记录的键值对转为数组,方便遍历渲染,完美适配未知键名的场景
  • String(value):确保所有值都转为字符串,避免React渲染非字符串/数字/布尔值时出错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:07:00