关于react.js:React报错之Objects-are-not-valid-as-a-React-child

注释从这开始~

总览

当咱们尝试在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',
  };

  // ⛔️ 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();

  // ⛔️ 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';

  // ⛔ 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);
  }

  // ⛔ 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函数。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理