Объекты недопустимы как дочерние объекты React. Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив

Я настраиваю приложение React с бэкэндом Rails. Я получаю сообщение об ошибке «Объекты недействительны в качестве дочерних элементов React (найдено: объект с ключами {id, name, info, created_at, updated_at}). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив».

Вот как выглядят мои данные:

[
    {
        "id": 1,
        "name": "Home Page",
        "info": "This little bit of info is being loaded from a Rails 
        API.",
        "created_at": "2018-09-18T16:39:22.184Z",
        "updated_at": "2018-09-18T16:39:22.184Z"
    }
]

Мой код выглядит следующим образом:

import React from 'react';

class Home extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      homes: []
    };
  }

  componentDidMount() {
    fetch('http://localhost:3000/api/homes')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            homes: result
          });
        },
        // error handler
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {

    const { error, isLoaded, homes } = this.state;

    if (error) {
      return (
        <div className = "col">
          Error: {error.message}
        </div>
      );
    } else if (!isLoaded) {
      return (
        <div className = "col">
          Loading...
        </div>
      );
    } else {
      return (
        <div className = "col">
          <h1>Mi Casa</h1>
          <p>This is my house y'all!</p>
          <p>Stuff: {homes}</p>
        </div>
      );
    }
  }
}

export default Home;

Что я делаю неправильно?

также вы можете попытаться убедиться, что при передаче параметра он заключен в фигурные скобки, чтобы его можно было рассматривать как ключ объекта (имя значения объектов)

Taiwo Fakayejo 16.07.2021 14:34
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
133
1
414 824
26
Перейти к ответу Данный вопрос помечен как решенный

Ответы 26

Ответ принят как подходящий

Ваши данные homes представляют собой массив, поэтому вам придется перебирать массив, используя Array.prototype.map (), чтобы он работал.

return (
    <div className = "col">
      <h1>Mi Casa</h1>
      <p>This is my house y&apos;all!</p>
      {homes.map(home => <div>{home.name}</div>)}
    </div>
  );

Сегодня у меня такая же ошибка, но с другим сценарием по сравнению со сценарием, опубликованным в этом вопросе. Надеюсь, что решение приведенного ниже сценария кому-то поможет.

Приведенной ниже функции render достаточно, чтобы понять мой сценарий и решение:

render() {
    let orderDetails = null;
    if (this.props.loading){
        orderDetails = <Spinner />;
    }
    if (this.props.orders.length == 0){
        orderDetails = null;
    }
    orderDetails = (
        <div>
            {
                this.props.orders && 
                this.props.orders.length > 0 && 
                this.props.orders.map(order => (
                <Order 
                    key = {order.id}
                    ingredient = {order.ingredients}
                    price = {order.price} />
                ))
            }
        </div>
    );
    return orderDetails;
}

В приведенном выше фрагменте кода: если return orderDetails отправляется как return {orderDetails}, то сообщение об ошибке, указанное в этом вопросе, появляется, несмотря на значение 'orderDetails' (значение как <Spinner/> или null или JSX, связанное с компонентом <Order />).

Описание ошибки: react-dom.development.js: 57 Неперехваченное инвариантное нарушение: объекты недействительны как дочерние объекты React (обнаружено: объект с ключами {orderDetails}). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив.

Мы не можем вернуть объект JavaScript из обратного вызова внутри метода render (). Причина в том, что React ожидает, что некоторые JSX, false, null, undefined, true будут отображаться в пользовательском интерфейсе, а НЕ какой-то объект JavaScript, который я пытаюсь отобразить, когда я использую return {orderDetails}, и, следовательно, получаю ошибку, как указано выше.

ДЕЙСТВИТЕЛЬНЫЙ :

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

НЕВЕРНЫЙ :

<div>{orderDetails}</div> // This is WRONG, orderDetails is an object and NOT a valid return value that React expects.

Редактировать: Я также получил эту ошибку на тестовом сервере моей компании, который использовался QA для тестирования. Я указал свой локальный код на этот тестовый сервер и протестировал сценарий, в котором команда QA сообщила об этой ошибке, и не обнаружил ОШИБКИ на моем локальном компьютере. Я был удивлен. Я перепроверил несколько раз, перепроверил сценарий с командой QA, и я все делал правильно, но все равно не смог воспроизвести проблему. Я посоветовался с коллегами-разработчиками, но так и не смог выяснить основную причину. Поэтому, следуя информации в сообщении об ошибке, я начал сканировать весь код, который я развернул в моем последнем коммите развертывания (точнее, последние 4-5 коммитов, потому что я подозревал, что он мог быть там из последних нескольких развертываний, но был пойман в текущем. развертывание), особенно все компоненты, которые я разработал, и обнаружил, что существует компонент - внутри которого не было соблюдено заданное условие, поэтому он НИЧЕГО не возвращал из него. Так что см. Ниже образец псевдокода. Я надеюсь, что это помогает.

render () {
return (
    {this.props.condition1 && (
       return some jsx 1
    )}

    {this.props.condition1 && (
       return some jsx 2
    )})
}

Если в приведенном выше псевдокоде вы видите, что условие1 и условие2 не выполняются, то этот компонент не будет отображать НИЧЕГО из него, и в идеале реагирующий компонент должен возвращать из него некоторый JSX, false, null, undefined, true.

В JavaScript массивы и коллекции разные, хотя они в чем-то похожи, но здесь для реакции нужен массив. Вам нужно создать array из collection и применить его.

let homeArray = new Array(homes.length);
let i = 0

for (var key in homes) {
    homeArray[i] =  homes[key];
    i = i + 1;
}

Я надеюсь, что это поможет кому-то другому.

Эта ошибка, по-видимому, возникает также, когда вы непреднамеренно отправляете сложный объект, который включает, например, дочерние компоненты Date to React.

Пример этого передается дочернему компоненту new Date ('....') следующим образом:

 const data = {name: 'ABC', startDate: new Date('2011-11-11')}
 ...
 <GenInfo params = {data}/>

Если вы отправите его как значение параметра дочернего компонента, вы отправите сложный объект, и вы можете получить ту же ошибку, что и указано выше.

Проверьте, не передаете ли вы что-то подобное (которое генерирует сложный объект под капотом). Вместо этого вы можете отправить эту дату как строковое значение и сделать новую дату (string_date) в дочернем компоненте.

Что значит «непреднамеренно»? Что не так с вашим примером? С каких это пор мы не можем передавать объекты в ReactJS? Я правда не понимаю, почему я получаю эту ошибку ..

wazus 26.03.2021 01:40

Была такая же проблема, в моем случае у меня была 1. Разберите строку в Json. 2. Убедитесь, что при визуализации мое представление пытается отобразить не весь объект, а object.value.

data = [
{
    "id": 1,
    "name": "Home Page",
    "info": "This little bit of info is being loaded from a Rails 
    API.",
    "created_at": "2018-09-18T16:39:22.184Z",
    "updated_at": "2018-09-18T16:39:22.184Z"
}];
var jsonData = JSON.parse(data)

Тогда мой взгляд

return (
<View style = {styles.container}>
  <FlatList
    data = {jsonData}
    renderItem = {({ item }) => <Item title = {item.name} />}
    keyExtractor = {item => item.id}
  />
</View>);

Поскольку я использую массив, я использовал плоский список для отображения и убедился, что работаю с object.value, а не с объектом, иначе вы получите ту же проблему.

Что ж, в моем случае данные, которые я хотел отобразить, содержали объект внутри массива, поэтому из-за этого он давал ошибку, поэтому для других людей также проверьте свои данные один раз, и если он содержит объект, вам нужно чтобы преобразовать его в массив для печати всех его значений или, если вам нужно конкретное значение, используйте.

Мои данные :

body: " d fvsdv"
photo: "http://res.cloudinary.com/imvr7/image/upload/v1591563988/hhanfhiyalwnv231oweg.png"
postedby: {_id: "5edbf948cdfafc4e38e74081", name: "vit"}       
//this is the object I am talking about.
title: "c sx "
__v: 0
_id: "5edd56d7e64a9e58acfd499f"
__proto__: Object

Чтобы напечатать только одно значение

<h5>{item.postedby.name}</h5>

Просто чтобы добавить к другим параметрам, я пытался получить доступ к вложенному объекту внутри основного объекта через точечный метод, как в: this.state.arrayData.CompleteAdress.Location В этом случае Место нахождения является вложенным объектом внутри Полный адрес, поэтому я не могу просто получить к нему доступ с помощью точечной нотации.

  • Поэтому, если вы столкнулись с той же проблемой, попробуйте JSON.parse, чтобы получить доступ к вложенному объекту и затем соответствующим образом выполнить необходимые действия.

Хотя это не относится к ответу, эта ошибка чаще всего возникает, когда вы ошибочно используете выражение JavaScript внутри контекста JavaScript с помощью {}

Например

let x=5;

export default function App(){ return( {x} ); };

Правильный способ сделать это:

let x=5;
export default function App(){ return( x ); };

Я столкнулся с той же проблемой, но теперь я рад решить эту проблему.

  1. npm i core-js
  2. поместите эту строку в первую строку вашего файла index.js. import core-js

У меня была аналогичная ошибка при создании пользовательского модального окна.

const CustomModal = (visible, modalText, modalHeader) => {}

Проблема заключалась в том, что я не заключал свои значения в фигурные скобки, как это.

const CustomModal = ({visible, modalText, modalHeader}) => {}

Если у вас есть несколько значений для передачи компоненту, вы должны заключить его в фигурные скобки.

Это тоже было решением моей проблемы, спасибо.

Michiel J Otto 19.03.2021 16:22

В вашем состоянии дом инициализируется как массив homes: []

В вашем возвращении будет попытка отрендерить дом (который представляет собой массив). <p>Stuff: {homes}</p>

Это невозможно сделать. Если вы хотите визуализировать это, вам нужно визуализировать массив в каждый отдельный элемент. Например: с использованием map()

Пример: {home.map(item=>item)}

Была та же ошибка, но с другим сценарием. У меня было состояние как

        this.state = {
        date: new Date()
    }

поэтому, когда я спрашивал об этом в своем компоненте класса, у меня было

p>Date = {this.state.date}</p>

Вместо того

p>Date = {this.state.date.toLocaleDateString()}</p>

У меня также возникла ошибка, и я решил ее, удалив фигурные скобки, надеюсь, это поможет кому-то другому.

Вы можете видеть, что я не вставлял con в фигурную скобку, и возникла ошибка, когда я удалил крупную скобу, ошибка исчезла.

const modal = (props) => {
const { show, onClose } = props;

let con = <div className = "modal" onClick = {onClose}>
        {props.children}
        </div>;

return show === true ? (
    {con}
) : (
    <div>hello</div>
);

Есть статья об использовании фигурной скобки.

У меня возникла эта проблема, когда я пытался визуализировать объект в дочернем компоненте, который получал реквизиты.

Я исправил это, когда понял, что мой код пытается отобразить объект, а не значение ключа объекта, которое я пытался отобразить.

В моем случае у меня был добавлен асинхронный режим в app.js, как показано ниже.

const App = async() => {
return(
<Text>Hello world</Text>
)
}

Но в этом не было необходимости, когда я что-то тестировал, я это добавил, и он больше не нужен. После его удаления, как показано ниже, все заработало.

 const App =() => {
    return(
    <Text>Hello world</Text>
    )
}

У меня была действительно похожая проблема. Если вы вызываете функцию в процессе рендеринга и она имеет асинхронный режим, она выдаст ошибку: Неперехваченное инвариантное нарушение: объекты недействительны как дочерние элементы React (найдено: объект с ключами {orderDetails}). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив. Просто удалите асинхронный режим, и все должно работать нормально.

Say u 09.07.2021 23:10

использовать формат момента, потому что это дата ... преобразовать в формат даты ... Момент (array_list_item.close_date) .format ("ММ-ДД-ГГГГ")}

Примечание: React не будет отображать этот тип формата даты в функции карты.

"created_at": "2018-09-18T16: 39: 22.184Z",

Пожалуйста, сделайте ответ более конструктивным, а не неверными утверждениями.

Gaurav Gupta 09.03.2021 15:26

хорошо, в следующий раз будет правильно добавлено

ajith 10.03.2021 16:09

Объекты недействительны как дочерние объекты React

У меня такая же ошибка, но с другим сценарием. Я учился реагировать на хук useReducer и реализовал счетчик с кнопками увеличения, уменьшения и сброса, и я пытался отобразить счет на экране, но я был вышеупомянутой ошибкой.

В коде я объявил счетчик, который возвращается хуком useReducer в качестве объекта, и я напрямую пытался вернуть его, а не его свойство count.

На самом деле я должен был вернуть count.count, и я возвращал только count (сам объект), а не свойство.

Мы можем преобразовать объект в строку и также вернуть строку.

import React, { useReducer } from "react";

const initialState = {
count:0,
}
const reducer = (state, action) => {
    switch (action.type) {
        case 'increment':
            return {count:state.count + 1}
        case 'decrement':
            return {count:state.count - 1}
        case 'reset':
            return initialState
        default:
            return state
    }
}

function CounterWithReducer(props) {
  const [count, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      <h1>{count}</h1>
      <button onClick = {()=>{dispatch({type:'increment'})}}>Increment</button>

      <button onClick = {()=>{dispatch({type:"decrement"})}}>Decrement</button>
      <button onClick = {()=>{dispatch({type:"reset"})}}>Reset</button>
    </>
  );
}

export default CounterWithReducer;

В приведенном выше коде

{считать}

В этом разделе (в части возврата) я допустил ошибку, вместо count мне нужно использовать count.count

Резюме заключается в том, что если вы пытаетесь отобразить объект на экране, вы не можете использоватьJSON.stringify()или попробуйте отобразить какое-либо свойство объекта.

Я нахожусь на раннем этапе моей жизни разработчика, пожалуйста, извините меня за любые орфографические ошибки, если таковые имеются.

Я столкнулся с этой точной ошибкой. При отслеживании основной причины этой проблемы я обнаружил, что код FRONTEND (React) вызывает API и показывает ответ на странице, обращаясь к некоторому свойству этого ответа! Итак, в этом случае есть два случая

  • Либо это свойство не существует в ответе от серверной части (это приведет к другой ошибке) ИЛИ
  • Свойство из ответа серверной части - это сложный объект (объект внутри объекта), к которому пытается получить доступ наш интерфейсный компонент React, но не может читать, потому что React требует либо STRING (путем прямого доступа к определенному свойству, например, Object.property), либо массиву. [Это дело]

Итак, мы получили эту ошибку, потому что React ожидал STRING, но получил объект (потому что вы передали Object внутри объекта).

Пожалуйста, проверьте свою внутреннюю логику (API), которая отправляет ответ.

У меня была аналогичная проблема, но у меня это сработало. Мой результат

Но ошибка, которую я совершил, была проста. В моем содержимом было больше двух, и я отказался обернуть как массив. Брекеты Карли я не ставила.

import React from 'react'
import {Button} from './Button';
import {Link} from 'react-router-dom'
import './HeroSection.css';

function HeroSection({
    lightBg, topLine, lightText, lightTextDesc, headline, description, 
    buttonLabel, img,alt,imgStart}
) {
    return (
        <>
            <div className = {lightBg? 'home__hero-section': 'home__hero-section darkBg'}>
                <div className='container'>
                    <div className = "row home__hero-row" 
                    style = {{display:'flex', flexDirection:imgStart==='start'?' row-reverse':'row'}}
                    >
                    <div className='col'>
                        <div className='home__hero-text-wrapper'>
                            <div className='topline'>{topLine}</div>
                            <h1 className = {lightText? 'heading': 'heading dark'}>{headline}</h1>
 <p className = {lightTextDesc? 'home__hero-subtitle': 'home__hero-subtitle dark'}> 
 {description}
 <Link to='/sign-up'>
     <Button buttonSize='btn--wide' buttonColor='blue'>
{buttonLabel}
     </Button>
 </Link>
 </p>
                        </div>

                    </div>

                    <div className='col'>
                        <div className='home__hero-img-wrapper'>
                      <img src = {img} alt = {alt} className='home_hero-img'/>
                        </div>
                    </div>
                    </div>

                </div>

            </div>

        </>
    );
}

export default HeroSection
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

У меня была эта ошибка при использовании библиотеки BigNumber для значения перед установкой на UseState:

const { toBN } = web3.utils;
...
 setOwner0Balance(toBN(await getBalance(owner0)));

Та же ошибка, но другой сценарий. Я намеревался назначить свой пользовательский функциональный компонент опоре layoutComponent стороннего модуля.

Ошибочный код:

customLayout = () => {
// function returning a component
}
//usage:
{customLayout}

Исправить:

CustomLayout = () => {
// functional component
}
//usage:
<CustomLayout></CustomLayout>

Есть еще один сценарий, который я запечатлел. Отрисовка модели DOM зависела от некоторых проверок. Поэтому я инициализировал его нулевым значением, а на Switch придал ему значение. И при возвращении просто вернул этот DOM.

export function test() {
  let DOM = null;
  switch (conditions) {
    case 1: {
      DOM = <div>SOME DIV</div>;
    }
    case 2: {
      DOM = <div>SOME DIV2</div>;
    }
    default: {
      DOM = null;
    }
  }
  return { DOM }; // -----1 Problem was here
}

Разрешение было просто обернуть его <> </>

return <>{DOM}</>

Я была такая же проблема. В моем случае я не отображал значение элемента. Мой первоначальный код был,

        keyExtractor = {(item, index) => item.id}
        data = {courseGoals} 
        renderItem = {itemData => (
          <View style = {styles.listitem}> 
              <Text>{itemData.item}</Text> 
          </View>
        )} 
      />

Я просто добавил .value, и это сработало!

        keyExtractor = {(item, index) => item.id}
        data = {courseGoals} 
        renderItem = {itemData => (
          <View style = {styles.listitem}> 
              <Text>{itemData.item.value}</Text> 
          </View>
        )} 
      />

В моем случае у меня было

 return (
    <div >
      {updated.map((one) => {
        <div>
          <h2>{one.name}</h2>
        </div>
      })}

    </div>
  );

Затем изменил на

 return (
    <div >
      {updated.map((one,index) => {
        return (
          <div key = {index}>
          <h2>{one.name}</h2>
          </div>
        )
      })}

    </div>
  );

Проблема заключалась в том, что у меня не было инструкции возвращение после функции карты

проблема в том, что вы пытаетесь отобразить объект целиком, а не ключи внутри объекта.

Например: данные

[
    {
        "status": "success",
        "count": 20511
    },
    {
        "status": "failure",
        "count": 1776
    }
]

Теперь, в компоненте, показанном ниже, это будет работать.

import React, { Component } from 'react';


export default class Display extends Component {

    render() {

        const { data } = this.props;

        return (
            <>
           
               {
                   data.map((value,key)=>
                       <div>{value.status}</div>
                       <div>{value.count}</div>
                   )
               }
            </>

        )
    }
}

Эта ошибка возникает у меня при отправке объекта Date (например, отметки времени в firebse) в дочерние компоненты React.

Если вы отправите его как значение параметра дочернего компонента, вы отправите сложный объект, и вы можете получить ту же ошибку, что и указано выше.

Вы должны отправить эту дату как строковое значение

        <p>{timestamp.toString()}</p>

должно работать нормально вот так.

Другие вопросы по теме