阅读 236

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

总览

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

objects-are-not-valid-as-react-child.png

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

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


作者:chuck
链接:https://juejin.cn/post/7128028629950267429
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐