node.js - 对象作为 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
我的代码如下:
- 服务器:carsModel.js:
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);
- 客户端:carList.js:
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
解决方案
为了扩展 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