首页 > 解决方案 > 对象作为 React 子对象无效(找到:带有键 {Owner1、Owner2、Owner3} 的对象)

问题描述

我正在尝试获取并显示 previousOwners,它是 MongoDB 模式中的对象数组。我已在架构中将类型列为“Array”,并尝试迭代 carList.js 文件中的项目。不幸的是,我收到以下错误消息:

Error: Objects are not valid as a React child (found: object with keys {Owner1, Owner2, Owner3}). If you meant to render a collection of children, use an array instead.
react-dom.development.js:13231 Uncaught Error: Objects are not valid as a React child (found: object with keys {Owner1, Owner2, Owner3}). If you meant to render a collection of children, use an array instead.
    at throwOnInvalidObjectType (react-dom.development.js:13231)
    at createChild (react-dom.development.js:13469)
    at reconcileChildrenArray (react-dom.development.js:13719)
    at reconcileChildFibers (react-dom.development.js:14125)
    at reconcileChildren (react-dom.development.js:16990)
    at updateHostComponent (react-dom.development.js:17632)
    at beginWork (react-dom.development.js:19080)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at beginWork$1 (react-dom.development.js:23964)
    at performUnitOfWork (react-dom.development.js:22776)
    at workLoopSync (react-dom.development.js:22707)
    at renderRootSync (react-dom.development.js:22670)
    at performSyncWorkOnRoot (react-dom.development.js:22293)
    at react-dom.development.js:11327
    at unstable_runWithPriority (scheduler.development.js:468)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
    at flushSyncCallbackQueue (react-dom.development.js:11309)
    at scheduleUpdateOnFiber (react-dom.development.js:21893)
    at dispatchAction (react-dom.development.js:16139)
    at carList.js:35
index.js:2178 The above error occurred in the <td> component:

    at td
    at tr
    at Car (http://localhost:3000/static/js/bundle.js:80229:13)
    at tbody
    at table
    at div
    at CarList (http://localhost:3000/static/js/bundle.js:80302:74)
    at div
    at div
    at App

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
Error: Objects are not valid as a React child (found: object with keys {Owner1, Owner2, Owner3}). If you meant to render a collection of children, use an array instead.
    at throwOnInvalidObjectType (react-dom.development.js:13231)
    at createChild (react-dom.development.js:13469)
    at reconcileChildrenArray (react-dom.development.js:13719)
    at reconcileChildFibers (react-dom.development.js:14125)
    at reconcileChildren (react-dom.development.js:16990)
    at updateHostComponent (react-dom.development.js:17632)
    at beginWork (react-dom.development.js:19080)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at beginWork$1 (react-dom.development.js:23964)
    at performUnitOfWork (react-dom.development.js:22776)
    at workLoopSync (react-dom.development.js:22707)
    at renderRootSync (react-dom.development.js:22670)
    at performSyncWorkOnRoot (react-dom.development.js:22293)
    at react-dom.development.js:11327
    at unstable_runWithPriority (scheduler.development.js:468)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
    at flushSyncCallbackQueue (react-dom.development.js:11309)
    at scheduleUpdateOnFiber (react-dom.development.js:21893)
    at dispatchAction (react-dom.development.js:16139)
    at carList.js:35

我的代码如下:

const mongoose = require("mongoose");

const carSchema = mongoose.Schema({
  Model: {
    type: String,
  },
  Make: {
    type: String,
  },
  Owner: {
    type: String,
  },
  Registration: {
    type: String,
  },
  Address: {
    type: String,
  },
  previousOwners: {
    type: Array,
  },
});

module.exports = mongoose.model("Cars", carSchema);
const Car = (props) => (
  <tr>
    <td>{props.car._id}</td>
    <td>{props.car.Model}</td>
    <td>{props.car.Make}</td>
    <td>{props.car.Registration}</td>
    <td>{props.car.Owner}</td>
    <td>{props.car.Address}</td>
    <td>{props.car.previousOwners}</td>
  </tr>
);

请在此处查看 GitHub 存储库的链接:https ://github.com/ChanBos/MERN-Cars-Database-Application

标签: node.jsreactjsmongodbexpress

解决方案


为了扩展 Drew Reese 所暗示的内容......

问题

React 不会渲染具有结构的数组。

例如:

const cars = [
  {
    _id: 1,
    Model: "Toyota",
    Make: "Tundra",
    Registration: "January 1st, 1970",
    Owner: "Owner 3",
    Address: "123 Example Street",
    previousOwners: [{ name: "Owner1" }, { name: "Owner2" }]
  },
  {
    _id: 2,
    Model: "Toyota",
    Make: "Tacoma",
    Registration: "January 1st, 1970",
    Owner: "Owner 6",
    Address: "123 Example Street",
    previousOwners: [{ name: "Owner4" }, { name: "Owner5" }]
  }
];

相反,您将处理所有数组的布局。

解决方案

更改您的CarList组件以处理previousOwners数组(假设它是一个对象数组),类似于您处理/映射car数组的方式:

// Imported react libraries and hooks.
import React, { useState, useEffect } from "react";
// Requiring Axios.
import axios from "axios";

/**
 * @param {*} props _id, Model, Make, Registration, Owner and Address.
 * @returns A table that displays all of the above mentioned information from the database.
 */

// Using object destructuring, destructure the car properties that will be rendered for the table output
const Car = ({ 
  _id, 
  Model, 
  Make, 
  Registration, 
  Owner, 
  Address, 
  previousOwners
}) => (
  <tr>
    <td>{_id}</td>
    <td>{Model}</td>
    <td>{Make}</td>
    <td>{Registration}</td>
    <td>{Owner}</td>
    <td>{Address}</td>
    {/* Change this next line to handle your previousOwners structure */}
    <td>{previousOwners.map(({ name }) => name).join(", ")}</td>
  </tr>
);

// Set the initial state of cars.
const CarList = () => {
  const [cars, setCars] = useState([]);

  // Utilized the useEffect() hook to get/ read the information from the database and respond displaying the data. If an error occurs the error
  // will be logged to console.
  useEffect(() => {
    axios
      .get("/cars/")
      .then((res) => {
        const data = res.data;
        setCars(data);
      })
      .catch((err) => console.log(err));
  }, []);

  return (
    <div id="listcontainer">
      <h6>Car List</h6>
      <table>
        <thead>
          <tr className="theaderrow">
            <th id="th-cell-left">ID</th>
            <th>Model</th>
            <th>Make</th>
            <th>Registration</th>
            <th>Owner</th>
            <th>Address</th>
            <th id="th-cell-right">Previous Owners</th>
          </tr>
        </thead>
        <tbody>{cars.map(car => <Car key={car._id} {...car} />)}</tbody>
      </table>
    </div>
  );
};

// Exported CarList to App.js.
export default CarList;

演示

编辑显示数据

进一步说明

Car组件使用对象解构来避免使用props.car.Property.

这一行: <tbody>{cars.map(car => <Car key={car._id} {...car} />)}</tbody>

意味着映射cars数组并为每个将其属性car 传播Car组件中

这一行:

<td>{previousOwners.map(({ name }) => name).join(", ")}</td>

previousOwners表示在数组上映射,并将name属性作为扁平的字符串数组返回:

["Owner1, "Owner2"]

然后join是带有逗号和空格(, )的字符串数组:

Owner1, Owner2


推荐阅读