Інваріантне порушення: Об'єкти не дійсні як дитина, що реагує


337

У функції візуалізації мого компонента у мене є:

render() {
    const items = ['EN', 'IT', 'FR', 'GR', 'RU'].map((item) => {
      return (<li onClick={this.onItemClick.bind(this, item)} key={item}>{item}</li>);
    });
    return (
      <div>
        ...
                <ul>
                  {items}
                </ul>
         ...
      </div>
    );
  }

все справляється нормально, проте при натисканні на <li>елемент я отримую таку помилку:

Неприхована помилка: Інваріантне порушення: Об'єкти недійсні як дитина-реагувач (знайдено: об’єкт з ключами {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, type, eventPhase, бульбашки, відміняється, timeStamp, defaultPrevented, isTrusted, view, деталь, screenX , screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, кнопка, кнопки, relatedTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}). Якщо ви мали намір видати колекцію дітей, використовуйте масив замість цього або оберніть об'єкт, використовуючи createFragment (об’єкт) з додатків React. Перевірте метод візуалізації Welcome.

Якщо я змінюю , this.onItemClick.bind(this, item)щоб (e) => onItemClick(e, item)усередині функції карти все працює , як очікувалося.

Якби хтось міг пояснити, що я роблю неправильно, і пояснити, чому я помиляюся, було б чудово

ОНОВЛЕННЯ 1:
Функція onItemClick полягає в наступному, і видалення this.setState призводить до зникнення помилок.

onItemClick(e, item) {
    this.setState({
      lang: item,
    });
}

Але я не можу видалити цей рядок, оскільки мені потрібно оновити стан цього компонента


2
То як this.onItemClickреалізується?
zerkms

@zerkms Дякую за відповідь, я оновив питання, і так, здається, проблема в цьому.setState (), але чому він кидає цю помилку? :(
almeynman

Чи є синтаксична помилка в setState? Додаткова кома? Можливо, не виправити помилку, а просто її виявити.
Bhargav Ponnapalli

Кома @bhargavponnapalli - це питання уподобань, моя eslint змушує мене це робити, але її видалення не допомагає, дякую за відповідь
almeynman

Я отримав цю помилку, коли забув фігурні дужки навколо змінної, яка стала об'єктом стану з локальної змінної після додавання її до стану в рефакторі.
jamescampbell

Відповіді:


398

У мене була ця помилка, і виявилося, що я ненавмисно включав Об'єкт у свій код JSX, який, як я очікував, буде значенням рядка:

return (
    <BreadcrumbItem href={routeString}>
        {breadcrumbElement}
    </BreadcrumbItem>
)

breadcrumbElementраніше був рядком, але завдяки рефактору став Об'єктом. На жаль, повідомлення про помилку React не зробило гарної роботи в тому, щоб вказати мені на лінію, де існувала проблема. Мені довелося стежити за моїм стеком стеження повністю назад, поки я не визнав, що "реквізит" передається в компонент, і тоді я знайшов код, що порушує.

Вам потрібно буде або посилатись на властивість об'єкта, що є значенням рядка, або перетворити Об'єкт на бажане подання рядка. Один з варіантів може бути, JSON.stringifyякщо ви дійсно хочете побачити вміст Об'єкта.


13
Отже, якщо у вас є об’єкт, як би ви перейшли до перетворення його на щось бажане?
adinutzyc21

4
Вам потрібно буде або посилатись на властивість об'єкта, що є значенням рядка, або перетворити Об'єкт на бажане подання рядка. Одним із варіантів може бути JSON.stringify, якщо ви насправді хочете побачити вміст Об'єкта.
Командир коду

2
Зустріли ту саму помилку, і це пояснення вирішило мою проблему. 1 UP для цього. :)
папський

Ага, у мене був такий самий випуск повідомлення про помилку, яке вказувало на неправильну лінію - воно сказало, що помилка була в this.setState ({items: items}), коли вона справді підірвалася далі, де я намагався відобразити цю змінну за допомогою { this.state.items}. JSON.stringify виправив це!
RubberDuckRabbit

Для майбутніх читачів: Ніхто не перетворюється на рядок. Зробіть це замість: const Lcomponent = this.wwhatReturnsObject (); тоді в render () {return <Lcomponent />} Це своє.
Нік

102

Тому я отримав цю помилку при спробі відобразити createdAtвластивість, яка є об'єктом Date. Якщо ви об'єднаєтеся .toString()в кінці таким чином, це зробить перетворення та усуне помилку. Просто опублікуйте це як можливу відповідь у випадку, якщо хтось інший зіткнувся з тією ж проблемою:

{this.props.task.createdAt.toString()}

2
Бінго! У мене була ця проблема, але вона була викинута з треку, тому що таблиця, яка її відображала, буде завантажуватись (і перезавантажуватись) просто чудово. Реагувати б тільки закинути objects are not validпорушення інваріанта , коли я додав рядок. Виявляється, я перетворював об’єкт Date () в рядок, перш ніж зберігати його, тому лише мої нові рядки мали об’єкти для створеної дати. :( Вчіться з мого нахабного прикладу людей!
Стів

37

Щойно я отримав ту саму помилку, але через іншу помилку: я використав подвійні дужки типу:

{{count}}

вставити значення countзамість правильного:

{count}

який, мабуть, перетворив компілятор {{count: count}}, тобто намагався вставити Об'єкт як дочірня Реакція.


3
для чого {{}} призначені /
Muneem Habib

4
@MuneemHabib це просто синтаксис ES6. Реагувати потрібно одна пара {}. Внутрішня пара трактується як код ES6. У ES6, {count}це те саме, що {count: count}. Отже, коли ви вводите {{count}}, це точно так само, як { {count: count} }.
Догберт

1
Якщо була ця помилка - в цьому і була проблема. При призначенні моєї змінної стану в конструкторі я мав this.state = {navMenuItems: {navMenu}};... що в основному перетворило мій JSX navMenuна загальний об'єкт. Змінившись, щоб this.state = {navMenuItems: navMenu};позбутися від ненавмисного «кидка», Objectі виправив проблему.
lowcrawler

30

Просто подумав, що я додам до цього, оскільки у мене була та сама проблема сьогодні, виявляється, це було тому, що я повертав саме цю функцію, коли я загорнув її в <div>тег, він почав працювати, як нижче

renderGallery() {
  const gallerySection = galleries.map((gallery, i) => {
    return (
      <div>
        ...
      </div>
    );
  });
  return (
    {gallerySection}
  );
}

Вище сказане спричинило помилку. Я вирішив проблему, змінивши return()розділ на:

return (
  <div>
    {gallerySection}
  </div>
);

... або просто:

return gallerySection

8
або ви можете просто скористатися, return gallerySectionякщо хочете уникнути зайвихdiv
Vishal

5
Повернення gallerySectionзамість <div>{gallerySection}</div>допомогло мені.
Занон

16

Реагувати дочірнє (сингулярне) повинно бути типом примітивного типу даних, а не об'єктом, або це мітка JSX (що в нашому випадку немає) . Використовуйте пакет Proptypes в розробці, щоб переконатися, що перевірка відбувається.

Просто порівняння фрагменту коду (JSX) для представлення вас ідеєю:

  1. Помилка: об'єкт передається дитині

    <div>
    {/* item is object with user's name and its other details on it */}
     {items.map((item, index) => {
      return <div key={index}>
    --item object invalid as react child--->>>{item}</div>;
     })}
    </div>
  2. Без помилок: властивість об'єкта ( яка повинна бути примітивною, тобто значення рядка або ціле число ) передається дочірній.

    <div>
     {/* item is object with user's name and its other details on it */}
      {items.map((item, index) => {
       return <div key={index}>
    --note the name property is primitive--->{item.name}</div>;
      })}
    </div>

TLDR; (З джерела нижче): Переконайтесь, що всі елементи, які ви надаєте в JSX, - примітиви, а не об'єкти, коли використовуєте React. Ця помилка зазвичай трапляється тому, що функції, яка бере участь у диспетчеризації події, було надано несподіваний тип об'єкта (тобто передача об'єкта, коли ви повинні передавати рядок) або частина JSX у вашому компоненті не посилається на примітив (тобто this.props vs this.props.name).

Джерело - codingbismuth.com


2
це посилання більше не працює, проте я вважаю структуру вашої відповіді найбільш інформативною у моєму випадку використання. Ця помилка створюється як в Інтернеті, так і в реагуванні на рідне середовище, і часто виникає як помилка життєвого циклу при спробі .map () масиву об'єктів всередині компонента за допомогою життєвого циклу async. Я натрапив на цю тему під час використання нативної реакції реакції-натискання
mibbit

Радий, що Ви вважаєте це корисним і дякую за проблему посилання на позначення.
Зустріньтеся із Завери

1
Це мені допомогло. Поверніть майно, а не об’єкт:return <p>{item.whatever}</p>;
Кріс,

15

Моє стосувалося зайвого розміщення фігурних дужок навколо змінної, що містить елемент HTML всередині оператора return функції render (). Це змусило React трактувати його як об'єкт, а не як елемент.

render() {
  let element = (
    <div className="some-class">
      <span>Some text</span>
    </div>
  );

  return (
    {element}
  )
}

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


Дякую! Зняти фігурні дужки з елемента працює і для мене!
Хуа Чжан

12

Моє стосувалося забуття фігурних брекетів навколо реквізиту, що надсилаються до презентаційного компонента:

Перед:

const TypeAheadInput = (name, options, onChange, value, error) => {

Після

const TypeAheadInput = ({name, options, onChange, value, error}) => {

1
Моя проблема була найбільш схожа на вашу, тому застосування вашого рішення допомогло мені. +1 і спасибі!
m1gp0z

9

Я теж отримував цю помилку "Об'єкти недійсні як дитина-реагувач", і для мене причина була викликана викликом асинхронної функції в моєму JSX. Дивись нижче.

class App extends React.Component {
    showHello = async () => {
        const response = await someAPI.get("/api/endpoint");

        // Even with response ignored in JSX below, this JSX is not immediately returned, 
        // causing "Objects are not valid as a React child" error.
        return (<div>Hello!</div>);
    }

    render() {
        return (
            <div>
                {this.showHello()}
            </div>
        );
    }
}

Я дізнався, що асинхронна візуалізація не підтримується в React. Команда React працює над рішенням, як це зафіксовано тут .


що замість цього потрібно зробити, це оновити стан при
надходженні

що замість цього потрібно зробити, це оновити стан при
надходженні

7

Для всіх, хто використовує Firebase з Android, це лише зламає Android. Моя емуляція iOS ігнорує це.

І як було вище розміщено Апоорвом Банкі.

Все, що вище Firebase V5.0.3, для Android, атм - це бюст. Виправити:

npm i --save firebase@5.0.3

Тут не раз підтверджувались https://github.com/firebase/firebase-js-sdk/isissue/871


Для тих, хто намагається знайти рішення, запропоноване KNDheeraj нижче, **** 1 голос "проти", якщо ви використовуєте Firebase будь-який з файлів у вашому проекті. Тоді просто помістіть цю імпортну заяву firebase наприкінці !! Я знаю, це звучить божевільно, але спробуйте !! **************** Я спробував це, і це не рішення для iOS, а лише для Android для Windows.
RedEarth

6

У мене теж є та ж проблема, але моя помилка така дурна. Я намагався отримати доступ до об’єкта безпосередньо.

class App extends Component {
    state = {
        name:'xyz',
        age:10
    }
    render() {
        return (
            <div className="App">
                // this is what I am using which gives the error
                <p>I am inside the {state}.</p> 

                //Correct Way is

                <p>I am inside the {this.state.name}.</p> 
            </div>
        );
    }                                                                             

}

4

Якщо ви чомусь імпортували Firebase. Потім спробуйте запустити npm i --save firebase@5.0.3. Це пояснюється тим, що розрив firebase є реактивним, тому запуск цього виправить це.


3

У моєму випадку я забув повернути HTML-елемент frm функцію візуалізації, і я повертав об'єкт. Що я зробив, я просто загорнув {items} елементами html - простим дівом, як показано нижче

<ul>{items}</ul>


3

У мене була така ж проблема, тому що я не ставив propsфігурні дужки.

export default function Hero(children, hero ) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}

Тож якщо ваш код схожий на наведений вище, ви отримаєте цю помилку. Щоб вирішити це, просто поставте фігурні дужки навколо props.

export default function Hero({ children, hero }) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}

@Dharman Я думаю, що це було добре зрозуміло ще до цього маленького відступу
Suresh Mangs

Я не сказав, що це не так. Я думаю, що ваша відповідь краще виглядає з відступом. Якщо ви не погоджуєтесь, будь ласка, сміливо поверніть її назад.
Дхарман

3

У мене така ж помилка, я це змінив

export default withAlert(Alerts)

до цього

export default withAlert()(Alerts).

У старих версіях колишній код був у порядку, але в пізніших версіях він видає помилку. Тому використовуйте пізніший код, щоб уникнути помилки.


3

У моєму випадку помилка сталася через те, що я повернув масив елементів у фігурних дужках а не просто повертав сам масив.

Код з помилкою

   render() {
        var rows = this.props.products.map(product => <tr key={product.id}><td>{product.name}</td><td>{product.price}</td></tr>
        );
        return {rows};
    }

Правильний код

render() {
    var rows = this.props.products.map(product => <tr key={product.id}><td>{product.name}</td><td>{product.price}</td></tr>
    );
    return rows;
}

2

Ви просто використовували клавіші об'єкта, а не цілий об'єкт!

Більш детальну інформацію можна знайти тут: https://github.com/gildata/RAIO/isissue/48

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class SCT extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            data: this.props.data,
            new_data: {}
        };
    }
    componentDidMount() {
        let new_data = this.state.data;
        console.log(`new_data`, new_data);
        this.setState(
            {
                new_data: Object.assign({}, new_data)
            }
        )
    }
    render() {
        return (
            <div>
                this.state.data = {JSON.stringify(this.state.data)}
                <hr/>
                <div style={{color: 'red'}}>
                    {this.state.new_data.name}<br />
                    {this.state.new_data.description}<br />
                    {this.state.new_data.dependtables}<br />
                </div>
            </div>
        );
    }
}

SCT.propTypes = {
    test: PropTypes.string,
    data: PropTypes.object.isRequired
};

export {SCT};
export default SCT;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


2

У мене те саме питання, і в моєму випадку я оновлюю скорочення стан , і нові параметри даних не відповідають старим параметрам. Тому, коли я хочу отримати доступ до деяких параметрів, це через цю помилку,

Можливо, цей досвід комусь допоможе


У моєму випадку (Django) ListSerializer та CreateSerializer повертають одні і ті ж поля, а деякі з них (це залежить від вашого проекту) - це поля лише для читання, тож завантажуйте раз і всякий раз, коли створюйте нові дані, просто оновіть стан
редукції

2

Якщо ви використовуєте Firebase і бачите цю помилку, варто перевірити, чи правильно ви імпортуєте її. З версії 5.0.4 вам потрібно імпортувати його так:

import firebase from '@firebase/app'
import '@firebase/auth';
import '@firebase/database';
import '@firebase/storage';

Так, я знаю. Я втратив і 45 хвилин на цьому.


Дякую. Це вирішило мою проблему з firebase (5.9.2) :)
Mate

2

Зазвичай це вискакує, оскільки ви не руйнуєтеся належним чином. Візьмемо, наприклад, цей код:

const Button = text => <button>{text}</button>

const SomeForm = () => (
  <Button text="Save" />
)

Ми декларуємо це = text =>парам. Але реально React очікує, що це буде всеохоплюючим propsоб’єктом.

Тож ми справді повинні робити щось подібне:

const Button = props => <button>{props.text}</button>

const SomeForm = () => (
  <Button text="Save" />
)

Помічаєте різницю? propsПарам тут можна було б назвати що - небудь (props це тільки умовність , яка відповідає номенклатурі), React просто чекає об'єкт з ключами і вальсом.

З деструктуризацією об'єктів ви можете робити і часто бачити щось подібне:

const Button = ({ text }) => <button>{text}</button>

const SomeForm = () => (
  <Button text="Save" />
)

... яка працює.

Можливо, хтось натрапив на це просто випадково оголосив реквізит свого реквізиту, не руйнуючись.


1

Я просто передавав себе справді нерозумною версією цієї помилки, якою я також можу поділитися тут для нащадків.

У мене був такий JSX:

...
{
  ...
  <Foo />
  ...
}
...

Мені потрібно було прокоментувати це, щоб щось налагодити. Я використовував комбінацію клавіш у своєму IDE, в результаті чого:

...
{
  ...
  { /* <Foo /> */ }
  ...
}
...

Що, звичайно, недійсне - об’єкти не дійсні, оскільки реагують діти!


1

Я хотів би додати ще одне рішення до цього списку.

Технічні характеристики:

  • "реагувати": "^ 16.2.0",
  • "react-dom": "^ 16.2.0",
  • "react-redux": "^ 5.0.6",
  • "react-script": "^ 1.0.17",
  • "скорочення": "^ 3.7.2"

Я зіткнувся з тією ж помилкою:

Неприхована помилка: Об'єкти недійсні як дитина-реагувач (знайдено: об’єкт з ключами {XXXXX}). Якщо ви мали намір надати колекцію дітей, використовуйте замість цього масив.

Це був мій код:

let payload = {
      guess: this.userInput.value
};

this.props.dispatch(checkAnswer(payload));

Рішення:

  // let payload = {
  //   guess: this.userInput.value
  // };

this.props.dispatch(checkAnswer(this.userInput.value));

Проблема виникла через те, що корисне навантаження відправляло елемент як об’єкт. Коли я видалив змінну корисного навантаження і помістив значення userInput в диспетчер, все почало працювати, як очікувалося.


1

Якщо ви використовуєте Firebase будь-який з файлів у вашому проекті. Тоді просто помістіть цю імпортну заяву firebase наприкінці !!

Я знаю, це звучить божевільно, але спробуйте !!


1

Моя проблема була простою, коли я зіткнувся з такою помилкою:

objects are not valid as a react child (found object with keys {...}

було лише те, що я передавав об'єкт із ключами, вказаними в помилці, намагаючись передати об’єкт безпосередньо в компонент, використовуючи {object} очікуючи, що він буде рядком

object: {
    key1: "key1",
    key2: "key2"
}

під час візуалізації на компоненті React, я використовував щось подібне нижче

render() {
    return this.props.object;
}

але це мало бути

render() {
    return this.props.object.key1;
}

1

Якщо ви використовуєте компоненти без громадянства, дотримуйтесь такого формату:

const Header = ({pageTitle}) => (
  <h1>{pageTitle}</h1>
);
export {Header};

Це, здавалося, працює для мене


1

Щось подібне зі мною щойно трапилося ...

Я написав:

{response.isDisplayOptions &&
{element}
}

Помістивши його всередині div, виправив його:

{response.isDisplayOptions &&
    <div>
        {element}
    </div>
}

1

Знайдено: об’єкт з ключами

Що означає, що ти передаєш щось, є ключовим значенням. Тому вам потрібно змінити обробник:

з
onItemClick(e, item) {
   this.setState({
     lang: item,
   });
}
до
onItemClick({e, item}) {
  this.setState({
    lang: item,
  });
}

Ви пропустили дужки ( {}).


1
не вірю, що це була проблема
kushal.8

Я також дивуюсь. досі не зрозуміли, в чому причина цього
Арул Мані

1

У моєму випадку я додав асинхроніку до дочірнього компонента функції своєї дитини і зіткнувся з цією помилкою. Не використовуйте async з дочірнім компонентом.


0

У разі використання Firebase, якщо вона не працює, поставивши в кінці importвисловлювань, ви можете спробувати помістити всередину один із методів життєвого циклу, тобто ви можете помістити його всередину componentWillMount().

componentWillMount() {
    const firebase = require('firebase');
    firebase.initializeApp({
        //Credentials
    });
}

0

Invariant Violation: Objects are not valid as a React childсталося зі мною під час використання компонента, який потребував renderItemреквізиту, наприклад:

renderItem={this.renderItem}

і моя помилка полягала в тому, щоб зробити свій renderItemметод async.


0

Моя помилка була через те, що я написав це так:

props.allinfo.map((stuff, i)=>{
  return (<p key={i}> I am {stuff} </p>)
})



замість:

props.allinfo.map((stuff, i)=>{
  return (<p key={i}> I am {stuff.name} </p>)
})

Це означало, що я намагаюся винести об'єкт замість значення в ньому.

редагувати: це для реакції не рідного.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.