对象作为 React 子对象无效。如果您打算渲染一组子项,请改用数组

IT技术 javascript arrays reactjs
2021-03-09 10:06:51

我正在设置一个带有 Rails 后端的 React 应用程序。我收到错误消息“对象作为 React 子对象无效(找到:带有键 {id, name, info, created_at, updated_at} 的对象)。如果您打算渲染子项集合,请改用数组。”

这是我的数据的样子:

[
    {
        "id": 1,
        "name": "Home Page",
        "info": "This little bit of info is being loaded from a Rails 
        API.",
        "created_at": "2018-09-18T16:39:22.184Z",
        "updated_at": "2018-09-18T16:39:22.184Z"
    }
]

我的代码如下:

import React from 'react';

class Home extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      homes: []
    };
  }

  componentDidMount() {
    fetch('http://localhost:3000/api/homes')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            homes: result
          });
        },
        // error handler
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {

    const { error, isLoaded, homes } = this.state;

    if (error) {
      return (
        <div className="col">
          Error: {error.message}
        </div>
      );
    } else if (!isLoaded) {
      return (
        <div className="col">
          Loading...
        </div>
      );
    } else {
      return (
        <div className="col">
          <h1>Mi Casa</h1>
          <p>This is my house y'all!</p>
          <p>Stuff: {homes}</p>
        </div>
      );
    }
  }
}

export default Home;

我究竟做错了什么?

6个回答

您的数据homes是一个数组,因此您必须使用Array.prototype.map()遍历该数组才能使其工作。

return (
    <div className="col">
      <h1>Mi Casa</h1>
      <p>This is my house y&apos;all!</p>
      {homes.map(home => <div>{home.name}</div>)}
    </div>
  );

我在创建自定义模态时遇到了类似的错误。

const CustomModal = (visible, modalText, modalHeader) => {}

问题是,根据 REACT 文档,我忘记了功能组件只能传递给它们一个 prop:

这个函数是一个有效的 React 组件,因为它接受一个带有数据的“props”(代表属性)对象参数并返回一个 React 元素。我们称这些组件为“函数组件”,因为它们实际上就是 JavaScript 函数。react文档

因此,当我们想要传递多个变量时,我们需要将它们包装成一个对象或一个数组,并将指针传递给该数组或对象。并在调用组件之前在组件端对其进行解构。或者,我们可以使用花括号来表示我们正在发送一个具有相同属性名称和包含这些属性值的变量的对象,就像这里的示例一样。然后定义函数来在对象中包含的属性到达时进行解构。

const CustomModal = ({visible, modalText, modalHeader}) => {}

如果您有多个值要传递给组件,则应该传递一个对象,因此在其属性/变量周围使用大括号(假设它们具有相同的名称)。

我今天遇到了同样的错误,但与此问题中发布的场景相比,场景有所不同。希望以下场景的解决方案对某人有所帮助。

render下面函数足以理解我的场景和解决方案:

render() {
    let orderDetails = null;
    if(this.props.loading){
        orderDetails = <Spinner />;
    }
    if(this.props.orders.length == 0){
        orderDetails = null;
    }
    orderDetails = (
        <div>
            {
                this.props.orders && 
                this.props.orders.length > 0 && 
                this.props.orders.map(order => (
                <Order 
                    key={order.id}
                    ingredient={order.ingredients}
                    price={order.price} />
                ))
            }
        </div>
    );
    return orderDetails;
}

在上面的代码片段中:如果return orderDetails发送为return {orderDetails}那么尽管'orderDetails'的值(组件相关的<Spinner/>null或JSX <Order />,该问题中发布的错误仍会弹出

错误描述:react-dom.development.js:57 Uncaught Invariant Violation: Objects is not valid as a React child (found: object with keys {orderDetails})。如果您打算渲染一组子项,请改用数组。

我们无法从 render() 方法内的返回调用返回 JavaScript 对象。原因是 React 期望在 UI 中呈现一些 JSX、false、null、undefined、true,而不是我在使用时尝试呈现的某些 JavaScript 对象,return {orderDetails}因此会出现上述错误。

有效的 :

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

无效的 :

<div>{orderDetails}</div> // This is WRONG, orderDetails is an object and NOT a valid return value that React expects.

编辑:我在 QA 用于测试的公司测试服务器上也出现了此错误。我将我的本地代码指向该测试服务器,并测试了 QA 团队报告此错误的场景,并在我的本地机器中发现没有错误。我很惊讶。我重新检查了多次,与 QA 团队重新检查了场景,我做得对,但仍然无法复制问题。我咨询了我的开发人员,但仍然无法找出根本原因。因此,根据错误消息中的信息,我开始扫描我在上次部署提交中部署的所有代码(更具体地说,最后 4-5 次提交,因为我怀疑它可能在最近几次部署中存在,但在当前部署),特别是我开发的所有组件,并发现有一个组件 - 在其中没有满足特定条件,因此它没有从中返回任何内容。所以请看下面的示例伪代码。我希望它有帮助。

render () {
return (
    {this.props.condition1 && (
       return some jsx 1
    )}

    {this.props.condition1 && (
       return some jsx 2
    )})
}

如果您在上面的伪代码中看到如果不满足条件 1 和条件 2,则该组件将不从中渲染任何内容,理想情况下,react组件必须从中返回一些 JSX、false、null、undefined、true。

我希望它会帮助别人。

当您无意中发送一个复杂的对象(例如包含 Date 到 React 子组件)时,似乎也会发生此错误。

它的示例是传递给子组件 new Date('....') 如下:

 const data = {name: 'ABC', startDate: new Date('2011-11-11')}
 ...
 <GenInfo params={data}/>

如果您将它作为子组件参数的值发送,您将发送一个复杂的对象,并且您可能会遇到与上述相同的错误。

检查您是否正在传递类似的东西(在引擎盖下生成复杂的对象)。相反,您可以将该日期作为字符串值发送并在子组件中执行 new Date(string_date) 。

你是什​​么意思“无意中”?你的例子有什么问题?从什么时候开始我们不能在 ReactJS 中传递对象?我不明白为什么我会收到这个错误..
2021-05-16 10:06:51

虽然不是特定于答案,但当您使用 {} 在 JavaScript 上下文中错误地使用 JavaScript 表达式时,通常会发生此错误

例如

let x=5;

export default function App(){ return( {x} ); };

这样做的正确方法是

let x=5;
export default function App(){ return( x ); };