web-dev-qa-db-fra.com

Violation invariante: les objets ne sont pas valides en tant qu'enfant de réaction

Dans la fonction de rendu de mon composant, j'ai:

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>
    );
  }

tout rend bien, cependant, lorsque je clique sur l'élément <li>, je reçois le message d'erreur suivant:

Erreur non capturée: violation invariante: les objets ne sont pas valides en tant que React child (trouvé: objet avec les clés {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, type, eventPhase, bubbles, cancelable, timeStamp, defaultPrevented, isTrusted, view, detail, screenX, screenY, clientX , clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, bouton, boutons, relatedTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}. Si vous vouliez rendre une collection d'enfants, utilisez plutôt un tableau ou enveloppez l'objet à l'aide de createFragment (object) à partir de les add-on React. Vérifiez la méthode de rendu de Welcome.

Si je change pour this.onItemClick.bind(this, item) en (e) => onItemClick(e, item) dans la fonction map, tout se passe comme prévu.

Si quelqu'un pouvait expliquer ce que je faisais mal et pourquoi je recevais cette erreur, ce serait génial.

MISE À JOUR 1:
La fonction onItemClick est la suivante et si vous supprimez this.setState, une erreur disparaît.

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

Mais je ne peux pas supprimer cette ligne car je dois mettre à jour l'état de ce composant

214
almeynman

J'avais cette erreur et il s'est avéré que j'ai involontairement inclus un objet dans mon code JSX que je m'attendais à être une valeur de chaîne:

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

breadcrumbElement était une chaîne, mais à cause d'un refactor, il était devenu un objet. Malheureusement, le message d'erreur de React n'a pas permis de me diriger vers la ligne où le problème existait. Je devais suivre ma trace de pile jusqu'à ce que je reconnaisse les "accessoires" transmis à un composant, puis je trouvais le code incriminé.

Vous devrez référencer une propriété de l'objet qui est une valeur de chaîne ou convertir l'objet en une représentation de chaîne souhaitable. Une option peut être JSON.stringify si vous voulez réellement voir le contenu de l'objet.

302
Code Commander

J'ai donc eu cette erreur en essayant d'afficher la propriété createdAt qui est un objet Date. Si vous concaténez .toString() à la fin de cette opération, la conversion sera effectuée et l’erreur éliminée. Publiant simplement ceci comme une réponse possible au cas où quelqu'un d'autre rencontrerait le même problème:

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

Je viens de recevoir la même erreur, mais à cause d'une erreur différente: j'ai utilisé des doubles accolades comme:

{{count}}

insérer la valeur de count au lieu de la valeur correcte:

{count}

que le compilateur a probablement transformé en {{count: count}}, c’est-à-dire en essayant d’insérer un objet en tant qu’enfant de React.

26
Dogbert

Je pensais que j’ajouterais à cela car j’avais le même problème aujourd’hui, mais c’est parce que je ne renvoyais que la fonction; quand je l’ai enveloppée dans une balise <div>, cela a commencé à fonctionner,

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

Ce qui précède a causé l'erreur. J'ai résolu le problème en modifiant la section return() en:

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

...ou simplement:

return gallerySection
20
user2997982

Mine devait mettre inutilement des accolades autour d'une variable contenant un élément HTML dans l'instruction return de la fonction render (). Cela a amené React à le traiter comme un objet plutôt que comme un élément.

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

  return (
    {element}
  )
}

Une fois que j'ai supprimé les accolades de l'élément, l'erreur a disparu et l'élément a été correctement rendu.

9
Liran H

La mienne avait pour but d’oublier les accolades entourant les accessoires envoyés à un élément de présentation:

Avant:

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

Après

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

Pour quiconque utilise Firebase avec Android, cela ne casse Android. Mon émulation iOS l'ignore.

Et comme posté par Apoorv Bankey ci-dessus. 

Quelque chose au-dessus de Firebase V5.0.3, pour Android, atm est un buste. Réparer:

npm i --save [email protected]

Confirmé à plusieurs reprises ici https://github.com/firebase/firebase-js-sdk/issues/871

7
RedEarth

Réagissez enfant/enfants doivent être de type primitif et non objet. Utilisez le package Proptypes en développement pour vous assurer que la validation est effectuée.

Juste un extrait de code rapide (JSX) pour vous représenter avec une idée:

  1. Erreur: avec l'objet étant passé dans l'enfant

    <div>
    {/* item is object with user's name and its other details on it */}
     {items.map((item, index) => {
      return <div key={index}>
    --item object is passed which is error--->>>{item}</div>;
     })}
    </div>
    
  2. Succès: avec la propriété de l’objet (qui doit être primitive, c’est-à-dire une valeur de chaîne ou une valeur entière) passée dans enfant.

    <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; (À partir du lien ci-dessous): Assurez-vous que tous les éléments que vous rendez dans JSX sont des primitives et non des objets lors de l'utilisation de React. Cette erreur se produit généralement lorsqu'un type d'objet inattendu a été attribué à une fonction impliquée dans la distribution d'un événement (par exemple, le passage d'un objet lorsque vous devez transmettre une chaîne) ou qu'une partie du fichier JSX de votre composant ne fait pas référence à une primitive (par exemple, this.props vs this.props.name).

Source - https://www.codingbismuth.com/objects-are-not-valid-as-react-child/

5
Meet Zaveri

Si, pour une raison quelconque, vous avez importé Firebase. Ensuite, essayez de lancer npm i --save [email protected]. Cela est dû au fait que firebase break réagit en mode natif, donc son exécution résoudra le problème. 

4
Apoorv Bankey

J'ai aussi le même problème mais mon erreur est tellement stupide. J'essayais d'accéder à l'objet directement.

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>
        );
    }                                                                             

}
3
Nimmi Verma

Quelque chose comme ça vient de m'arriver ...

J'ai écrit:

{response.isDisplayOptions &&
{element}
}

Le placer à l'intérieur d'une div le fixe:

{response.isDisplayOptions &&
    <div>
        {element}
    </div>
}
2
Oranit Dar

Vous utilisiez juste les clés d'objet, au lieu de tout l'objet!

Plus de détails peuvent être trouvés ici: https://github.com/gildata/RAIO/issues/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
user8202629

Mon problème était simple lorsque j'ai fait face à l'erreur suivante:

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

était juste que je passais un objet avec les clés spécifiées dans l'erreur en essayant de rendre l'objet directement dans un composant en utilisant {objet} en supposant qu'il s'agisse d'une chaîne

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

lors du rendu sur un composant React, j'ai utilisé quelque chose comme ci-dessous

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

mais ça aurait dû être

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

J'aimerais ajouter une autre solution à cette liste.

Spécifications:

  • "réagir": "^ 16.2.0",
  • "react-dom": "^ 16.2.0",
  • "react-redux": "^ 5.0.6",
  • "react-scripts": "^ 1.0.17",
  • "redux": "^ 3.7.2"

J'ai rencontré la même erreur:

Erreur non capturée: les objets ne sont pas valides en tant qu’enfants de React (trouvés: objet .__ avec les clés {XXXXX}). Si vous vouliez rendre une collection d'enfants, utilisez plutôt un tableau.

C'était mon code:

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

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

Solution:

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

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

Le problème était dû au fait que la charge utile envoyait l'élément sous forme d'objet. Lorsque j'ai supprimé la variable de charge utile et mis la valeur userInput dans la répartition, tout a commencé à fonctionner comme prévu.

1
bprdev

J'ai le même problème, dans mon cas, Je mets à jour le redux state et les nouveaux paramètres de données ne correspondent pas aux anciens paramètres

Peut-être que cette expérience aidera quelqu'un 

1
MohammadMasoumi

Si vous utilisez des composants sans état, suivez ce type de format:

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

Cela a semblé fonctionner pour moi

1
ppak10

Si dans le cas où vous utilisez Firebase, l’un des fichiers de votre projet . Ensuite, placez simplement cette instruction import Firebase à la fin!

Je sais que cela semble fou, mais essayez-le!

1
KNDheeraj

J'avais moi aussi l'erreur "Les objets ne sont pas valides en tant qu'enfant de React" et la cause en était due à l'appel d'une fonction asynchrone dans mon JSX. Voir ci-dessous.

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>
        );
    }
}

Ce que j'ai appris, c'est que le rendu asynchrone n'est pas pris en charge dans React. L’équipe de React travaille sur une solution documentée ici .

Ken

1
Ken A Collins

Mon problème était très particulier: dans mon fichier .env, je mettais un commentaire dans la ligne qui contenait mon URL api:

API_URL=https://6ec1259f.ngrok.io #comment

J'obtiendrais l'erreur Invariant violation en essayant de me connecter/de m'inscrire, car l'URL de l'API était fausse.

0
ehacinom

J'ai eu cette erreur rendant quelque chose dans un opérateur ternaire. Ce que j'ai fait:

render(){
  const bar = <div>asdfasdf</div>
  return ({this.state.foo ? {bar} : <div>blahblah</div>})
}

Il s'avère que cela devrait être barre sans les crochets, comme:

render(){
  const bar = <div>asdfasdf</div>
  return ({this.state.foo ? bar : <div>blahblah</div>})
}
0
Acy

Mon erreur était due à l'écrire de cette façon:

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



au lieu de:

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

Cela signifiait que j'essayais de rendre un objet à la place de la valeur qu'il contenait.

edit: c'est pour réagir pas natif.

0
Deke

Dans mon cas, c’était j’avais oublié de retourner un élément html de la fonction de rendu et j’étais en train de retourner un objet. Ce que j’ai fait c’est que je viens d’envelopper les {items} avec un élément html - un simple div comme ci-dessous

<ul>{items}</ul>

0
Shan

J'ai eu le même problème parce que je n'ai pas mis le props entre les accolades.

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

Donc, si votre code est similaire au précédent, vous obtiendrez cette erreur. Pour résoudre ce problème, il suffit de mettre des accolades autour de la props.

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

Invariant Violation: Objects are not valid as a React child m'est arrivé lors de l'utilisation d'un composant nécessitant un accessoire renderItem, tel que:

renderItem={this.renderItem}

et mon erreur a été de rendre ma méthode renderItemasync.

0
vmarquet

Dans mon cas, c'était à cause d'un tableau dynamique qui devait être injecté à l'exécution.

Je viens d'ajouter les contrôles nuls d'objet et cela a bien fonctionné.

Avant:

...
render(
...
    <div> {props.data.roles[0]} </div>
...
);

Après:

...
let items = (props && props.data && props.data.roles)? props.data.roles: [];
render(
...
    <div> {items[i]} </div>
...
);
0
Yuvraj Patil

Créez simplement un élément JSX valide. Dans mon cas, j'ai affecté un composant à un objet.

const AwesomeButtonComponent = () => <button>AwesomeButton</button>
const next = {
  link: "http://awesomeLink.com",
  text: "Awesome text",
  comp: AwesomeButtonComponent
}

Quelque part dans mon code, je voulais assigner ce bouton de manière dynamique.

return (
  <div>
    {next.comp ? next.comp : <DefaultAwesomeButtonComp/>}
  </div>
)

Je résous ce problème en déclarant une maquette JSX que j'ai initialisée via le props comp.

const AwesomeBtnFromProps = next.comp
return (
  <div>
    {next.comp ? <AwesomeBtnFromProps/> : <DefaultAwesomeButtonComp/>}
  </div>
)
0
Matthis Kohli

Base de feu 2019

Si vous utilisez Firebase et voyez cette erreur, vérifiez si vous l'importez correctement. A partir de la version 5.0.4, vous devez l'importer comme ceci:

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

Oui je sais. J'ai aussi perdu 45 minutes à ce sujet.

0
Lucas Bustamante

Pour ceux qui ont mentionné Stringify() et toString() comme solution, je dirai que cela a fonctionné pour moi, mais nous devons comprendre le problème et pourquoi il s'est produit. Dans mon code c'était un problème simple. J'avais 2 boutons qui appellent même fonction mais un bouton ne passait pas l'argument à cette fonction correctement.

0
Tanaka
  1. La fonction onClick que vous essayez d'implémenter est immédiatement exécutée.

  2. Comme notre code n'est pas HTML, c'est du javascript, il est donc interprété comme une exécution de fonction.

  3. la fonction onClick prend une fonction en tant qu'argument et non une exécution de fonction.

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

cela définira une fonction onClick sur l'élément de la liste qui sera exécutée après avoir cliqué dessus dès que notre composant sera rendu.

0
Hassan Raza

En cas d'utilisation de Firebase, si cela ne fonctionne pas en mettant des instructions à la fin de import, vous pouvez essayer de l'insérer dans l'une des méthodes du cycle de vie, c'est-à-dire de l'insérer dans componentWillMount().

componentWillMount() {
    const firebase = require('firebase');
    firebase.initializeApp({
        //Credentials
    });
}
0
Germa Vinsmoke
try{
    throw new Error(<p>An error occured</p>)
}catch(e){
    return (e)
}

Le code ci-dessus a généré l'erreur, je l'ai ensuite réécrit comme ceci:

try{
    throw(<p>An error occured</p>)
}catch(e){
    return (e)
}

Prenez note de la suppression de nouvelle erreur () dans le bloc try ...

Un meilleur moyen d'écrire le code afin d'éviter ce message d'erreur Attendu qu'un objet soit jeté no-throw-literal est de passer une chaîne dans renvoie une nouvelle erreur () au lieu de JSX et renvoie JSX dans votre bloc de capture, quelque chose comme ceci:

try{
    throw new Error("An error occurred")
}catch(e){
    return (
        <p>{e.message}</p>
    )
}
0
Peter Moses Mohemos

Vous pouvez afficher un tableau directement dans le texte. soit vous devez strignify ou iterate tableau et afficher dans FlatList

Par exemple this.props.items = ["A", "B", "C"]

vous devez afficher comme <Text>{JSON.strignify(this.props.items)}</Text>

ou

 <FlatList
    data={this.props.items}
    renderItem={(item)=>{
    <Text>{item}</Text>
    }}
     />
0
Rajesh Nasit

Je viens de me mettre à travers une version vraiment stupide de cette erreur, que je pourrais aussi bien partager ici pour la postérité.

J'ai eu un peu de JSX comme ça:

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

Je devais commenter ceci pour déboguer quelque chose. J'ai utilisé le raccourci clavier dans mon IDE, ce qui a abouti à ceci:

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

Ce qui est, bien sûr, invalide - les objets ne sont pas valides car réagissent enfants!

0
shabs

Trouvé: objet avec clés

Ce qui signifie que vous passez quelque chose est une valeur-clé, vous devez donc modifier votre gestionnaire.

de

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

À

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

Vous avez manqué les accolades ({}).

0
Arul Mani