React报错之Objects are not valid as a React child

更新日期: 2022-08-05阅读: 930标签: React

总览

当我们尝试在JSX代码中,直接渲染对象或者数组时,会产生 "Objects are not valid as a react child" 错误。为了解决该错误,在JSX代码中,使用 map() 方法来渲染数组或者访问对象的属性。


下面是错误如何发生的示例。

export default function App() {
  const employees = [
    {id: 1, name: 'Alice', country: 'Austria'},
    {id: 2, name: 'Bob', country: 'Belgium'},
    {id: 3, name: 'Carl', country: 'Canada'},
  ];

  const obj = {
    id: 4,
    name: 'Dean',
    country: 'Denmark',
  };

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

  return (
    <div>
      {employees}

      {obj}
    </div>
  );
}

map

上述代码片段的问题在于,在JSX代码中我们尝试直接渲染数组或者对象。

为了解决该错误,当渲染JSX代码时,使用 map() 方法来渲染数组或者访问对象的属性。

export default function App() {
  const employees = [
    {id: 1, name: 'Alice', country: 'Austria'},
    {id: 2, name: 'Bob', country: 'Belgium'},
    {id: 3, name: 'Carl', country: 'Canada'},
  ];

  const obj = {
    id: 4,
    name: 'Dean',
    country: 'Denmark',
  };

  return (
    <div>
      {employees.map((employee, index) => {
        return (
          <div key={index}>
            <h2>name: {employee.name}</h2>
            <h2>country: {employee.country}</h2>

            <hr />
          </div>
        );
      })}

      <hr />
      <hr />
      <hr />

      <div>
        <h2>name: {obj.name}</h2>
        <h2>county: {obj.country}</h2>
      </div>

      <hr />
    </div>
  );
}

当调试时,可以使用 console.log 来打印导致错误的值。

JSON.stringify

或者,你可以在JSX代码中使用 JSON.stringify() 转换该值,以确保它是预期的类型。

export default function App() {
  const employees = [
    {id: 1, name: 'Alice', country: 'Austria'},
    {id: 2, name: 'Bob', country: 'Belgium'},
    {id: 3, name: 'Carl', country: 'Canada'},
  ];

  const obj = {
    id: 4,
    name: 'Dean',
    country: 'Denmark',
  };

  return (
    <div>
      <h4>{JSON.stringify(employees)}</h4>

      <h4>{JSON.stringify(obj)}</h4>
    </div>
  );
}

JSON.stringify() 方法将会在对象渲染之前,将其转换为字符串。

你必须确保在JSX代码中,不会渲染对象或者数组。相反,你必须渲染原始值,比如说字符串以及数值。

Date

另一个导致该错误的常见原因是,在JSX代码中我们试图直接渲染 Date 对象时。

export default function App() {
  const date = new Date();

  // :no_entry:️ Objects are not valid as a React child (found: [object Date]).
  return (
    <div>
      <h4>{date}</h4>
    </div>
  );
}

为了解决该问题,我们必须访问 Date 对象上的方法,比如说, toLocaleDateString() 。

export default function App() {
  return (
    <div>
      <h4>{date.toLocaleDateString()}</h4>
    </div>
  );
}

现在,我们使用字符串代替对象来进行渲染,因此该错误被解决。

花括号

如果错误依旧存在,请确保当渲染变量时,你没有使用双花括号。

export default function App() {
  const message = 'hello world';

  // :no_entry: Objects are not valid as a React child (found: object with keys {message}).
  return (
    <div>
      <h4>{{message}}</h4>
    </div>
  );
}

注意 message 变量包裹在两组花括号内,这也是为什么React认为尝试渲染一个对象。为了解决该问题,可以只将变量包裹在一组大括号中。

export default function App() {
  return (
    <div>
      <h4>{message}</h4>
    </div>
  );
}

现在React把 message 变量当作一个包含字符串的表达式,而不是一个对象。

async

如果错误依旧存在,请确保在JSX代码中没有调用 async 函数

async 函数返回一个 Promise 对象,因此在JSX代码中,如果调用了 async 函数,则错误就会发生。

export default function App() {
  async function getData() {
    return Promise.resolve(42);
  }

  // :no_entry: Objects are not valid as a React child (found: [object Promise]).
  return (
    <div>
      <h4>{getData()}</h4>
    </div>
  );
}

为了解决该错误,我们必须在 useEffect 钩子或者事件处理器里调用 async 函数,比如说, onClick 。

import {useEffect, useState} from 'react';

export default function App() {
  const [num, setNum] = useState(0);

  useEffect(() => {
    async function getData() {
      const result = await Promise.resolve(42);

      setNum(result);
    }

    getData();
  }, []);

  return (
    <div>
      <h4>{num}</h4>
    </div>
  );
}

在 useEffect 钩子中调用 async 函数可以解决这个错误,因为我们现在渲染的是一个数字,而不是 Promise 对象。

总结

发生 "Objects are not valid as a React child" 的React错误有多种原因:

  • 在JSX代码中直接渲染对象或者数组;
  • 在JSX代码中直接渲染 Date 对象;
  • 在两组花括号中包裹变量,比如: {{message}} 而不是 {message} ;
  • 在JSX代码中调用 async 函数。

来源:https://bobbyhadz.com/blog/react-objects-are-not-valid-as-react-child

链接: https://fly63.com/article/detial/11983

如何优雅的设计 React 组件

如今的 Web 前端已被 React、Vue 和 Angular 三分天下,尽管现在的 jQuery 已不再那么流行,但 jQuery 的设计思想还是非常值得致敬和学习的,特别是 jQuery 的插件化。

React深度编程:受控组件与非受控组件

受控组件与非受控组件在官网与国内网上的资料都不多,有些人觉得它可有可不有,也不在意。这恰恰显示React的威力,满足不同规模大小的工程需求。

React框架学习_关于React两种构建应用方式选择

一般在传统模式下,我们构建前端项目很简单。就是下载各种js文件,如JQuery、Echart等,直接放置在html静态文件。Webpack则是JavaScript中比较知名的打包工具。这两个构建工具构成了React应用快速搭建的基础。

Gatsby.js_一款基于React.js静态站点生成工具

Gatsby能快速的使用 React 生态系统来生成静态网站,可以结合React Component、Markdown 和服务端渲染来完成静态网站生成让他更强大。

React创建组件的三种方式及其区别

React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归;具体的三种方式:函数式定义的无状态组件、es5原生方式React.createClass定义的组件、es6形式的extends React.Component定义的组件

react生命周期详解_深入理解React生命周期

React主要思想是通过构建可复用组件来构建用户界面,每个组件都有自己的生命周期,它规定了组件的状态和方法需要在哪个阶段改变和执行。所谓组件就是有限状态机,,表示有限个状态以及在这些状态之间的转移和动作行为的模型。

React + Webpack 构建打包优化

React 相关的优化:使用 babel-react-optimize 对 React 代码进行优化,检查没有使用的库,去除 import 引用,按需打包所用的类库,比如 lodash 、echarts 等.Webpack 构建打包存在的问题两个方面:构建速度慢,打包后的文件体积过大

react router中页面传值的三种方法

这篇文章主要介绍React Router定义路由之后如何传值,有关React和React Router 。react router中页面传值的三种方法:props.params、query、state

react 高阶组件的 理解和应用

react 高阶组件简单的理解是:一个包装了另一个基础组件的组件。高阶组件的两种形式:属性代理(Props Proxy)、反向继承 (Inheritance Inversion)

react中的refs属性的使用方法

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!