陌上傾寒 發表於 2022-8-4 22:34:00

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

<p>正文从这开始~</p>
<h2 id="总览">总览</h2>
<p>当我们尝试在JSX代码中,直接渲染对象或者数组时,会产生<code>"Objects are not valid as a React child"</code>错误。为了解决该错误,在JSX代码中,使用<code>map()</code>方法来渲染数组或者访问对象的属性。</p>
<p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0f854507f66f4081be1c21777b0b6516~tplv-k3u1fbpfcp-watermark.image?"></p>
<p>下面是错误如何发生的示例。</p>
<pre><code class="language-jsx">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 (
    &lt;div&gt;
      {employees}

      {obj}
    &lt;/div&gt;
);
}
</code></pre>
<h2 id="map">map</h2>
<p>上述代码片段的问题在于,在JSX代码中我们尝试直接渲染数组或者对象。</p>
<p>为了解决该错误,当渲染JSX代码时,使用<code>map()</code>方法来渲染数组或者访问对象的属性。</p>
<pre><code class="language-jsx">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 (
    &lt;div&gt;
      {employees.map((employee, index) =&gt; {
      return (
          &lt;div key={index}&gt;
            &lt;h2&gt;name: {employee.name}&lt;/h2&gt;
            &lt;h2&gt;country: {employee.country}&lt;/h2&gt;

            &lt;hr /&gt;
          &lt;/div&gt;
      );
      })}

      &lt;hr /&gt;
      &lt;hr /&gt;
      &lt;hr /&gt;

      &lt;div&gt;
      &lt;h2&gt;name: {obj.name}&lt;/h2&gt;
      &lt;h2&gt;county: {obj.country}&lt;/h2&gt;
      &lt;/div&gt;

      &lt;hr /&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>当调试时,可以使用<code>console.log</code>来打印导致错误的值。</p>
<h2 id="jsonstringify">JSON.stringify</h2>
<p>或者,你可以在JSX代码中使用<code>JSON.stringify()</code>转换该值,以确保它是预期的类型。</p>
<pre><code class="language-jsx">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 (
    &lt;div&gt;
      &lt;h4&gt;{JSON.stringify(employees)}&lt;/h4&gt;

      &lt;h4&gt;{JSON.stringify(obj)}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p><code>JSON.stringify()</code>方法将会在对象渲染之前,将其转换为字符串。</p>
<blockquote>
<p>你必须确保在JSX代码中,不会渲染对象或者数组。相反,你必须渲染原始值,比如说字符串以及数值。</p>
</blockquote>
<h2 id="date">Date</h2>
<p>另一个导致该错误的常见原因是,在JSX代码中我们试图直接渲染<code>Date</code>对象时。</p>
<pre><code class="language-jsx">export default function App() {
const date = new Date();

// ⛔️ Objects are not valid as a React child (found: ).
return (
    &lt;div&gt;
      &lt;h4&gt;{date}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>为了解决该问题,我们必须访问<code>Date</code>对象上的方法,比如说,<code>toLocaleDateString()</code> 。</p>
<pre><code class="language-jsx">export default function App() {
return (
    &lt;div&gt;
      &lt;h4&gt;{date.toLocaleDateString()}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>现在,我们使用字符串代替对象来进行渲染,因此该错误被解决。</p>
<h2 id="花括号">花括号</h2>
<p>如果错误依旧存在,请确保当渲染变量时,你没有使用双花括号。</p>
<pre><code class="language-jsx">export default function App() {
const message = 'hello world';

// ⛔ Objects are not valid as a React child (found: object with keys {message}).
return (
    &lt;div&gt;
      &lt;h4&gt;{{message}}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>注意<code>message</code>变量包裹在两组花括号内,这也是为什么React认为尝试渲染一个对象。为了解决该问题,可以只将变量包裹在一组大括号中。</p>
<pre><code class="language-jsx">export default function App() {
return (
    &lt;div&gt;
      &lt;h4&gt;{message}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>现在React把<code>message</code>变量当作一个包含字符串的表达式,而不是一个对象。</p>
<h2 id="async">async</h2>
<p>如果错误依旧存在,请确保在JSX代码中没有调用<code>async</code>函数。</p>
<p><code>async</code>函数返回一个<code>Promise</code>对象,因此在JSX代码中,如果调用了<code>async</code>函数,则错误就会发生。</p>
<pre><code class="language-jsx">export default function App() {
async function getData() {
    return Promise.resolve(42);
}

// ⛔ Objects are not valid as a React child (found: ).
return (
    &lt;div&gt;
      &lt;h4&gt;{getData()}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>为了解决该错误,我们必须在<code>useEffect</code>钩子或者事件处理器里调用<code>async</code>函数,比如说,<code>onClick</code>。</p>
<pre><code class="language-jsx">import {useEffect, useState} from 'react';

export default function App() {
const = useState(0);

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

      setNum(result);
    }

    getData();
}, []);

return (
    &lt;div&gt;
      &lt;h4&gt;{num}&lt;/h4&gt;
    &lt;/div&gt;
);
}
</code></pre>
<p>在<code>useEffect</code>钩子中调用<code>async</code>函数可以解决这个错误,因为我们现在渲染的是一个数字,而不是<code>Promise</code>对象。</p>
<h2 id="总结">总结</h2>
<p>发生<code>"Objects are not valid as a React child"</code>的React错误有多种原因:</p>
<ul>
<li>在JSX代码中直接渲染对象或者数组;</li>
<li>在JSX代码中直接渲染<code>Date</code>对象;</li>
<li>在两组花括号中包裹变量,比如:<code>{{message}}</code>而不是<code>{message}</code>;</li>
<li>在JSX代码中调用<code>async</code>函数。</li>
</ul><br><br>
来源:https://www.cnblogs.com/chuckQu/p/16552571.html
頁: [1]
查看完整版本: React报错之Objects are not valid as a React child