Violazione invariante: gli oggetti non sono validi come figlio React


337

Nella funzione di rendering del mio componente ho:

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

tutto viene <li>visualizzato correttamente , tuttavia quando si fa clic sull'elemento viene visualizzato il seguente errore:

Errore non rilevato: violazione invariante: gli oggetti non sono validi come figlio React (trovato: oggetto con chiavi {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, tipo, eventPhase, bolle, annullabile, timeStamp, defaultPrevented, isTrusted, view, detail, screenX , screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, pulsante, pulsanti, relativiTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}). Se intendevi eseguire il rendering di una raccolta di elementi secondari, utilizza invece un array o avvolgi l'oggetto utilizzando createFragment (oggetto) dai componenti aggiuntivi di React. Controlla il metodo di rendering di Welcome.

Se cambio al this.onItemClick.bind(this, item)di (e) => onItemClick(e, item)dentro il tutto funziona mappa funzionare come previsto.

Se qualcuno potesse spiegare cosa sto facendo di sbagliato e spiegare perché visualizzo questo errore, sarebbe fantastico

AGGIORNAMENTO 1: la
funzione onItemClick è la seguente e la rimozione di this.setState provoca la scomparsa dell'errore.

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

Ma non riesco a rimuovere questa linea poiché devo aggiornare lo stato di questo componente


2
Quindi, come this.onItemClickviene implementato?
zerkms,

@zerkms Grazie per la risposta, ho aggiornato la domanda, e sì sembra che il problema sia in this.setState (), ma perché genera questo errore? :(
almeynman,

C'è un errore di sintassi in setState? Una virgola extra? Potrebbe non correggere l'errore, ma l'ho appena trovato.
Bhargav Ponnapalli,

La virgola @bhargavponnapalli è una questione di preferenza, il mio eslint mi costringe a farlo, ma rimuoverlo non aiuta, grazie per la risposta
almeynman,

Ho ricevuto questo errore quando ho dimenticato le parentesi graffe attorno a una variabile che era diventata un oggetto pieno di stato dalla variabile locale dopo averlo aggiunto allo stato nel refactor.
Jamescampbell,

Risposte:


398

Stavo avendo questo errore e si è scoperto che stavo includendo involontariamente un oggetto nel mio codice JSX che mi aspettavo fosse un valore di stringa:

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

breadcrumbElementera una stringa ma a causa di un refattore era diventato un oggetto. Sfortunatamente, il messaggio di errore di React non ha fatto un buon lavoro indicandomi la linea in cui si è verificato il problema. Ho dovuto seguire il mio stack stack fino a quando non ho riconosciuto gli "oggetti di scena" passati in un componente e poi ho trovato il codice offensivo.

Dovrai fare riferimento a una proprietà dell'oggetto che è un valore stringa o convertire l'Oggetto in una rappresentazione stringa che è desiderabile. Un'opzione potrebbe essere JSON.stringifyse si desidera effettivamente vedere il contenuto dell'oggetto.


13
Quindi, se hai un oggetto, come potresti trasformarlo in qualcosa di desiderabile?
adinutzyc21,

4
Dovrai fare riferimento a una proprietà dell'oggetto che è un valore stringa o convertire l'Oggetto in una rappresentazione stringa che è desiderabile. Un'opzione potrebbe essere JSON.stringify se si desidera effettivamente vedere il contenuto dell'oggetto.
Codice comandante

2
Si è verificato lo stesso errore e questa spiegazione ha risolto il mio problema. 1 UP per questo. :)
papski

Ah, ho avuto lo stesso problema del messaggio di errore che puntava alla riga sbagliata - diceva che l'errore si trovava in this.setState ({items: items}) quando in realtà è esploso più in basso dove stavo cercando di visualizzare quella variabile usando { this.state.items}. JSON.stringify ha risolto il problema!
RubberDuckRabbit

Per i lettori futuri: No, non convertire in stringa. Fallo invece: const Lcomponent = this.whateverReturnsObject (); quindi in render () {return <Lcomponent />} Questo è il suo.
Nick,

102

Quindi ho riscontrato questo errore nel tentativo di visualizzare la createdAtproprietà che è un oggetto Date. Se concatenate .toString()alla fine in questo modo, eseguirà la conversione ed eliminerà l'errore. Pubblicando questa come una possibile risposta nel caso in cui qualcun altro avesse riscontrato lo stesso problema:

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

2
Bingo! Ho avuto questo problema ma sono stato scartato perché la tabella che lo stava visualizzando si sarebbe caricata (e ricaricata) bene. React lanciava la objects are not validviolazione invariante solo quando aggiungevo una riga. Si scopre che stavo convertendo l'oggetto Date () in una stringa prima di persisterlo, quindi solo le mie nuove righe avevano oggetti per la data di creazione. :( Impara dal mio esempio ribelle di persone!
Steve,

37

Ho appena ricevuto lo stesso errore, ma a causa di un errore diverso: ho usato doppie parentesi graffe come:

{{count}}

per inserire il valore di countanziché il corretto:

{count}

in cui il compilatore presumibilmente si è trasformato {{count: count}}, cioè cercando di inserire un oggetto come figlio React.


3
cosa significa {{}} per /
Muneem Habib il

4
@MuneemHabib è solo sintassi ES6. React ha bisogno di una coppia di {}. La coppia interna viene considerata come codice ES6. In ES6, {count}è uguale a {count: count}. Quindi quando digiti {{count}}, è esattamente lo stesso di { {count: count} }.
Dogbert,

1
Ha avuto questo errore - questo era il problema. Nell'assegnare la mia variabile allo stato nel costruttore avevo this.state = {navMenuItems: {navMenu}};... che sostanzialmente trasformava il mio JSX navMenuin un oggetto generico. Cambiare per this.state = {navMenuItems: navMenu};sbarazzarsi del "cast" involontario Objecte risolvere il problema.
lowcrawler,

30

Ho pensato di aggiungere a questo dato che ho avuto lo stesso problema oggi, si scopre che era perché stavo restituendo solo la funzione, quando l'ho avvolta in un <div>tag ha iniziato a funzionare, come di seguito

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

Quanto sopra ha causato l'errore. Ho risolto il problema modificando la return()sezione in:

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

... o semplicemente:

return gallerySection

8
oppure puoi semplicemente usare return gallerySectionse vuoi evitare un extradiv
Vishal,

5
Tornare gallerySectioninvece di <div>{gallerySection}</div>aiutarmi.
Zanon,

16

React child (singolare) dovrebbe essere un tipo di tipo di dati primitivo non oggetto o potrebbe essere un tag JSX (che non è nel nostro caso) . Utilizzare il pacchetto Proptypes in fase di sviluppo per assicurarsi che avvenga la convalida.

Solo un confronto di frammenti di codice rapido (JSX) per rappresentarti con l'idea:

  1. Errore: con l'oggetto passato al figlio

    <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. Senza errori: la proprietà dell'oggetto ( che dovrebbe essere primitiva, ovvero un valore stringa o valore intero ) viene passata al figlio.

    <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; (Dalla fonte in basso): assicurati che tutti gli elementi che stai riproducendo in JSX siano primitivi e non oggetti quando usi React. Questo errore si verifica in genere perché a una funzione coinvolta nell'invio di un evento è stato assegnato un tipo di oggetto imprevisto (ovvero passaggio di un oggetto quando si dovrebbe passare una stringa) o parte di JSX nel proprio componente non fa riferimento a una primitiva (ovvero this.props vs this.props.name).

Fonte: codingbismuth.com


2
questo link non funziona più, tuttavia trovo che la struttura della tua risposta sia la più informativa nel mio caso d'uso. Questo errore è producibile in entrambi gli ambienti Web e di reazione e si presenta spesso come errore del ciclo di vita quando si tenta di .map () una matrice di oggetti all'interno di un componente utilizzando il ciclo di vita asincrono. Mi sono imbattuto in questo thread durante l'utilizzo di React native native-scrollview
mibbit il

Sono contento che lo trovi utile e grazie per aver segnalato il problema del collegamento.
Incontra Zaveri il

1
Questo mi ha aiutato. Restituisce una proprietà anziché un oggetto:return <p>{item.whatever}</p>;
Chris

15

Il mio ha avuto a che fare con l'inserimento inutile di parentesi graffe attorno a una variabile che contiene un elemento HTML all'interno dell'istruzione return della funzione render (). Ciò ha fatto sì che React lo trattasse come un oggetto piuttosto che un elemento.

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

  return (
    {element}
  )
}

Dopo aver rimosso le parentesi graffe dall'elemento, l'errore è scomparso e l'elemento è stato visualizzato correttamente.


Grazie! Rimuovere le parentesi graffe dall'elemento funziona anche per me!
Hua Zhang,

12

Il mio aveva a che fare con l'oblio delle parentesi graffe attorno agli oggetti di scena inviati a un componente di presentazione:

Prima:

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

Dopo

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

1
Il mio problema era molto simile al tuo, quindi l'applicazione della tua soluzione mi ha aiutato. +1 e grazie!
m1gp0z,

9

Anch'io stavo ricevendo questo errore "Gli oggetti non sono validi come figlio React" e per me la causa era dovuta alla chiamata di una funzione asincrona nel mio JSX. Vedi sotto.

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

Quello che ho imparato è che il rendering asincrono non è supportato in React. Il team di React sta lavorando a una soluzione come documentato qui .


quello che dovresti invece fare è aggiornare lo stato man mano che arrivano i dati e quindi renderizzare i componenti usando i valori di stato
mrwagaba

quello che dovresti invece fare è aggiornare lo stato man mano che arrivano i dati e quindi renderizzare i componenti usando i valori di stato
mrwagaba

7

Per chiunque utilizzi Firebase con Android, questo rompe solo Android. La mia emulazione iOS la ignora.

E come pubblicato da Apoorv Bankey sopra.

Qualunque cosa sopra Firebase V5.0.3, per Android, atm è un fallimento. fix:

npm i --save firebase@5.0.3

Confermato numerose volte qui https://github.com/firebase/firebase-js-sdk/issues/871


Per chiunque stia tentando la soluzione proposta da KNDheeraj in basso, **** 1 voto in negativo Se si utilizza Firebase uno dei file all'interno del proprio progetto. Quindi posiziona l'istruzione firebase di importazione alla fine !! So che sembra folle ma provalo !! **************** L'ho provato e questa non è una soluzione per iOS ma per Android solo su Windows.
RedEarth

6

Ho anche lo stesso problema, ma il mio errore è così stupido. Stavo cercando di accedere direttamente all'oggetto.

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

Se per qualche motivo hai importato firebase. Quindi prova a correre npm i --save firebase@5.0.3. Questo perché Firebase Break reagisce in modo nativo, quindi eseguirlo risolverà il problema.


3

Nel mio caso, ho dimenticato di restituire un elemento HTML dalla funzione di rendering e stavo restituendo un oggetto. Quello che ho fatto è stato semplicemente avvolto gli {items} con un elemento html, un semplice div come di seguito

<ul>{items}</ul>


3

Ho avuto lo stesso problema perché non ho inserito le propsparentesi graffe.

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

Quindi se il tuo codice è simile a quello sopra, otterrai questo errore. Per risolvere questo, basta mettere parentesi graffe intorno al props.

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

@Dharman Penso che questo sia stato ben compreso anche prima di questo piccolo rientro
Suresh Mangs,

Non ho detto che non lo era. Penso che la tua risposta abbia un aspetto migliore con il rientro. Se non sei d'accordo, ti invitiamo a ripristinarlo.
Dharman,

3

Ho avuto lo stesso errore, ho cambiato questo

export default withAlert(Alerts)

a questa

export default withAlert()(Alerts).

Nelle versioni precedenti il ​​codice precedente era ok, ma nelle versioni successive genera un errore. Quindi utilizzare il codice successivo per evitare l'errore.


3

Nel mio caso l'errore si stava verificando perché ho restituito la matrice di elementi tra parentesi graffe invece di restituire la matrice stessa.

Codice con errore

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

Codice corretto

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

2

Stavi solo usando le chiavi dell'oggetto, anziché l'intero oggetto!

Maggiori dettagli sono disponibili qui: 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

Ho lo stesso problema, nel mio caso, aggiorno lo stato di redux e i nuovi parametri di dati non corrispondevano ai vecchi parametri, quindi quando voglio accedere ad alcuni parametri tramite questo errore,

Forse questa esperienza aiuta qualcuno


Nel mio caso, (Django) ListSerializer e CreateSerializer restituiscono gli stessi campi e alcuni di essi (dipende dal tuo progetto) sono solo campi di sola lettura, quindi recupera una volta e ogni volta che crei nuovi dati semplicemente aggiorna lo stato di redux
Mohammad Masoumi

2

Se stai usando Firebase e vedi questo errore, vale la pena controllare se lo stai importando nel modo giusto. A partire dalla versione 5.0.4 devi importarlo in questo modo:

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

Si, lo so. Ho perso 45 minuti anche su questo.


Grazie. Ha risolto il mio problema con Firebase (5.9.2) :)
Mate

2

In genere questo si apre perché non si distrugge correttamente. Prendi questo codice per esempio:

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

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

Lo stiamo dichiarando con il = text =>parametro. Ma davvero, React si aspetta che questo sia un propsoggetto onnicomprensivo .

Quindi dovremmo davvero fare qualcosa del genere:

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

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

Notare la differenza? Il propsparametro qui potrebbe essere chiamato qualunque cosa ( propsè solo la convenzione che corrisponde alla nomenclatura), React si aspetta solo un oggetto con chiavi e val.

Con la distruzione degli oggetti puoi fare, e vedrai spesso, qualcosa del genere:

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

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

... che funziona.

È probabile che chiunque inciampare in questo abbia appena dichiarato per errore i parametri dei propri componenti senza distruggere.


1

Ho appena passato una versione davvero stupida di questo errore, che potrei anche condividere qui per i posteri.

Ho avuto alcuni JSX come questo:

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

Ho dovuto commentarlo per eseguire il debug di qualcosa. Ho usato la scorciatoia da tastiera nel mio IDE, che ha portato a questo:

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

Che è, ovviamente, non valido - gli oggetti non sono validi come reagire ai bambini!


1

Vorrei aggiungere un'altra soluzione a questo elenco.

Specifiche:

  • "reagire": "^ 16.2.0",
  • "reazioni-dom": "^ 16.2.0",
  • "reply-redux": "^ 5.0.6",
  • "reazioni-script": "^ 1.0.17",
  • "redux": "^ 3.7.2"

Ho riscontrato lo stesso errore:

Errore non rilevato: gli oggetti non sono validi come figlio React (trovato: oggetto con chiavi {XXXXX}). Se intendevi eseguire il rendering di una raccolta di figli, utilizza invece un array.

Questo era il mio codice:

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

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

Soluzione:

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

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

Il problema si stava verificando perché il payload stava inviando l'articolo come oggetto. Quando ho rimosso la variabile payload e ho inserito il valore userInput nella spedizione, tutto ha iniziato a funzionare come previsto.


1

Se nel caso in cui si utilizza Firebase uno dei file all'interno del progetto. Quindi posiziona l'istruzione firebase di importazione alla fine !!

So che sembra folle ma provalo !!


1

Il mio problema era semplice quando ho riscontrato il seguente errore:

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

era solo che stavo passando un oggetto con le chiavi specificate nell'errore mentre cercavo di renderizzare l'oggetto direttamente in un componente usando {oggetto} aspettandomi che fosse una stringa

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

durante il rendering su un componente React, ho usato qualcosa di simile al di sotto

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

ma avrebbe dovuto essere

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

1

Se si utilizzano componenti senza stato, seguire questo tipo di formato:

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

Questo sembra funzionare per me


1

Qualcosa del genere mi è appena successo ...

Scrissi:

{response.isDisplayOptions &&
{element}
}

Inserendolo all'interno di un div è stato risolto:

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

1

Trovato: oggetto con chiavi

Ciò significa che passare qualcosa è un valore-chiave. Quindi è necessario modificare il gestore:

a partire dal
onItemClick(e, item) {
   this.setState({
     lang: item,
   });
}
per
onItemClick({e, item}) {
  this.setState({
    lang: item,
  });
}

Ti sei perso le parentesi graffe ( {}).


1
non riesco a credere che questo sia stato il problema
kushal.8

mi chiedo anche. non ho ancora capito quale sia la causa di questo problema
Arul Mani

1

Nel mio caso, ho aggiunto un asincrono al componente della funzione figlio e ho riscontrato questo errore. Non utilizzare asincronizzazione con componente figlio.


0

In caso di utilizzo di Firebase, se non funziona inserendo alla fine delle importistruzioni, puoi provare a inserirlo all'interno di uno dei metodi del ciclo di vita, ovvero puoi inserirlo all'interno componentWillMount().

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

0

Invariant Violation: Objects are not valid as a React childmi è successo quando ho usato un componente che aveva bisogno di renderItemoggetti di scena, come:

renderItem={this.renderItem}

e il mio errore è stato quello di rendere il mio renderItemmetodo async.


0

Il mio errore è stato a causa della scrittura in questo modo:

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



invece di:

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

Significava che stavo provando a rendere l'oggetto invece del valore al suo interno.

modifica: questo è per reagire non nativo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.