Я настраиваю приложение 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;
Что я делаю неправильно?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ваши данные homes представляют собой массив, поэтому вам придется перебирать массив, используя Array.prototype.map (), чтобы он работал.
return (
<div className = "col">
<h1>Mi Casa</h1>
<p>This is my house y'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? Я правда не понимаю, почему я получаю эту ошибку ..
Была такая же проблема, в моем случае у меня была 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
В этом случае Место нахождения является вложенным объектом внутри Полный адрес, поэтому я не могу просто получить к нему доступ с помощью точечной нотации.
Хотя это не относится к ответу, эта ошибка чаще всего возникает, когда вы ошибочно используете выражение JavaScript внутри контекста JavaScript с помощью {}
Например
let x=5;
export default function App(){ return( {x} ); };
Правильный способ сделать это:
let x=5;
export default function App(){ return( x ); };
Я столкнулся с той же проблемой, но теперь я рад решить эту проблему.
npm i core-jsindex.js.
import core-jsУ меня была аналогичная ошибка при создании пользовательского модального окна.
const CustomModal = (visible, modalText, modalHeader) => {}
Проблема заключалась в том, что я не заключал свои значения в фигурные скобки, как это.
const CustomModal = ({visible, modalText, modalHeader}) => {}
Если у вас есть несколько значений для передачи компоненту, вы должны заключить его в фигурные скобки.
Это тоже было решением моей проблемы, спасибо.
В вашем состоянии дом инициализируется как массив
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}). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив. Просто удалите асинхронный режим, и все должно работать нормально.
использовать формат момента, потому что это дата ... преобразовать в формат даты ... Момент (array_list_item.close_date) .format ("ММ-ДД-ГГГГ")}
Примечание: React не будет отображать этот тип формата даты в функции карты.
"created_at": "2018-09-18T16: 39: 22.184Z",
Пожалуйста, сделайте ответ более конструктивным, а не неверными утверждениями.
хорошо, в следующий раз будет правильно добавлено
Объекты недействительны как дочерние объекты 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 ожидал 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>
должно работать нормально вот так.
также вы можете попытаться убедиться, что при передаче параметра он заключен в фигурные скобки, чтобы его можно было рассматривать как ключ объекта (имя значения объектов)