【问题标题】:How to fix 'Objects are not valid as a React child'如何修复“对象作为 React 子项无效”
【发布时间】:2019-07-10 16:35:55
【问题描述】:

Codesandbox link.

我在尝试通过大量对象(定义为“filteredCharacters”)使用 filter() 时遇到此错误,并且仅将那些与“6”的 id 匹配的对象渲染到屏幕上(只有一个对象)。

我 console.log(filteredCharacters),我可以在控制台中清楚地看到它有效。但由于某种原因,我收到了“Objects are not valid as a React child”错误。

下面的代码来自 /components/content.js,在上面的 Codesandbox 链接中。

import React, { Component } from 'react';
import Intro from '../intro/intro';

class Content extends Component {
  render() {
    // Grab the 'characters' object from App.js, and assign it to 'this.props'
    const { characters } = this.props;

    // Filter the chracters and return only whose 'id' belongs to that of '6'
    const filteredCharacters = characters.filter(characters => {
      if (characters.id === 6) {
        return (
          <div className="characters" key={characters.id}>
            <p>Name: {characters.Name}</p>
            <p>ID: {characters.id}</p>
            <p>Job: {characters.Job}</p>
            <p>Age: {characters.Age}</p>
            <p>Weapon: {characters.Weapon}</p>
            <p>Height: {characters.Height}</p>
            <p>Birthdate: {characters.Birthdate}</p>
            <p>Birthplace: {characters.Birthplace}</p>
            <p>Bloodtype: {characters.Bloodtype}</p>
            <p>Description: {characters.Description}</p>
          </div>
        )
      }
    });

    // Check to see if it logs properly (it does)
    console.log(filteredCharacters);

    // When trying to render this to the screen below, it doesn't work

    return (
      <div>
        {filteredCharacters}
      </div>
    )
  }
}

export default Content;

【问题讨论】:

  • filter 接受一个返回布尔值的谓词来决定如果为真则保留哪些元素,如果为假则跳过
  • filteredCharacters 数组的成员是对象,在渲染这些对象时会出现此错误

标签: javascript arrays reactjs object


【解决方案1】:

目前,您正在使用一个简单的对象来充当您正在编写的组件的 HTML 结构中的一个节点。在这种情况下使用 react 的最佳实践之一是创建并调用它作为一个 react 组件本身。

以下是您的代码,现在有一个可以根据需要调用的单独组件:

import React, { Component } from 'react';
import Intro from '../intro/intro';

const FilteredCharcters = characters => {
  characters.filter(character => {
   if (character.id === 6) {
     return (
       <div className="characters" key={character.id}>
         <p>Name: {character.Name}</p>
         <p>ID: {character.id}</p>
         <p>Job: {character.Job}</p>
         <p>Age: {character.Age}</p>
         <p>Weapon: {character.Weapon}</p>
         <p>Height: {character.Height}</p>
         <p>Birthdate: {character.Birthdate}</p>
         <p>Birthplace: {character.Birthplace}</p>
         <p>Bloodtype: {character.Bloodtype}</p>
         <p>Description: {character.Description}</p>
       </div>
     )
   }
 });

class Content extends Component {

  render() {
  const { characters } = this.props;
    return (
      <div>
        <FilteredCharacters characters={characters} />
      </div>
    )
  }
}

export default Content;

【讨论】:

    【解决方案2】:

    除了@Tholle 的回答,您可以将这些操作与reduce 合二为一

    const filteredCharacters = characters
      .reduce((acc, character)  => {
    
        if (character.id !== 6) return acc;
    
        acc.push(<div className="characters" key={character.id}>
          <p>Name: {character.Name}</p>
          <p>ID: {character.id}</p>
          <p>Job: {character.Job}</p>
          <p>Age: {character.Age}</p>
          <p>Weapon: {character.Weapon}</p>
          <p>Height: {character.Height}</p>
          <p>Birthdate: {character.Birthdate}</p>
          <p>Birthplace: {character.Birthplace}</p>
          <p>Bloodtype: {character.Bloodtype}</p>
          <p>Description: {character.Description}</p>
        </div>);
    
        return acc;
      }, []);
    

    【讨论】:

      【解决方案3】:

      filter 只会创建一个包含所有从函数返回真值的元素的新数组。

      您可以改为先使用filter 来获取相关字符,然后在新数组上使用map 来获取您要渲染的JSX。

      const filteredCharacters = characters
        .filter(character => character.id === 6)
        .map(character => (
          <div className="characters" key={character.id}>
            <p>Name: {character.Name}</p>
            <p>ID: {character.id}</p>
            <p>Job: {character.Job}</p>
            <p>Age: {character.Age}</p>
            <p>Weapon: {character.Weapon}</p>
            <p>Height: {character.Height}</p>
            <p>Birthdate: {character.Birthdate}</p>
            <p>Birthplace: {character.Birthplace}</p>
            <p>Bloodtype: {character.Bloodtype}</p>
            <p>Description: {character.Description}</p>
          </div>
        ));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-26
        • 1970-01-01
        • 1970-01-01
        • 2020-09-03
        • 2021-12-02
        • 1970-01-01
        • 2021-02-24
        相关资源
        最近更新 更多