Pelanggaran Invarian: Objek tidak valid sebagai anak Bereaksi

337

Dalam fungsi render komponen saya, saya memiliki:

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

semuanya membuat baik-baik saja, namun ketika mengklik <li>elemen saya menerima kesalahan berikut:

Uncaught Error: Pelanggaran Invarian: Objek tidak valid sebagai anak Bereaksi (ditemukan: objek dengan kunci {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, jenis, eventPhase, gelembung, dapat dibatalkan, timeStamp, defaultPrevented, isTrusted, view, detail, screenX , screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, tombol, tombol, terkait Target, pageX, halamanY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}). Jika Anda bermaksud merender koleksi anak-anak, gunakan array atau bungkus objek menggunakan createFragment (objek) dari React add-ons. Periksa metode render dari Welcome.

Jika saya beralih ke this.onItemClick.bind(this, item)ke (e) => onItemClick(e, item)dalam fungsi peta semuanya berfungsi seperti yang diharapkan.

Jika seseorang dapat menjelaskan apa yang saya lakukan salah dan menjelaskan mengapa saya mendapatkan kesalahan ini, akan sangat bagus

UPDATE 1:
fungsi onItemClick adalah sebagai berikut dan menghapus this.setState mengakibatkan kesalahan menghilang.

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

Tetapi saya tidak dapat menghapus baris ini karena saya perlu memperbarui status komponen ini

almeynman
sumber
2
Lantas bagaimana this.onItemClickimplementasinya?
zerkms
@zerkms Terima kasih telah membalas, saya memperbarui pertanyaan, dan ya sepertinya masalahnya ada di this.setState (), tetapi mengapa ia membuang kesalahan ini? :(
almeynman
Apakah ada kesalahan sintaksis di setState? Koma ekstra? Mungkin tidak memperbaiki kesalahan, tetapi baru saja menemukannya.
Bhargav Ponnapalli
@bhargavponnapalli koma adalah masalah preferensi, eslint saya memaksa saya untuk melakukan itu, tetapi menghapusnya tidak membantu, terima kasih atas balasan
almeynman
Saya mendapatkan kesalahan ini ketika saya lupa kawat gigi keriting di sekitar variabel yang telah menjadi objek state-ful dari variabel lokal setelah menambahkannya ke negara dalam refactor.
jamescampbell

Jawaban:

398

Saya mengalami kesalahan ini dan ternyata saya tidak sengaja memasukkan Obyek dalam kode JSX yang saya harapkan menjadi nilai string:

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

breadcrumbElementDulu string tetapi karena refactor telah menjadi Obyek. Sayangnya, pesan kesalahan React tidak melakukan pekerjaan yang baik dalam mengarahkan saya ke garis di mana masalah itu ada. Saya harus mengikuti jejak stack saya kembali ke atas sampai saya mengenali "alat peraga" yang dilewatkan ke dalam komponen dan kemudian saya menemukan kode yang menyinggung.

Anda harus mereferensikan properti objek yang merupakan nilai string atau mengonversi Obyek ke representasi string yang diinginkan. Salah satu opsi mungkin JSON.stringifyjika Anda benar-benar ingin melihat konten Obyek.

Komandan Kode
sumber
13
Jadi, jika Anda memiliki objek, bagaimana Anda mengubahnya menjadi sesuatu yang diinginkan?
adinutzyc21
4
Anda harus mereferensikan properti objek yang merupakan nilai string atau mengonversi Obyek ke representasi string yang diinginkan. Salah satu opsi mungkin JSON.stringify jika Anda benar-benar ingin melihat konten Objek.
Code Commander
2
Mengalami kesalahan yang sama dan penjelasan ini menyelesaikan masalah saya. 1 UP untuk ini. :)
papski
Ahh, saya memiliki masalah yang sama dari pesan kesalahan yang menunjuk ke baris yang salah - katanya kesalahan ada di this.setState ({items: items}) ketika benar-benar meledak lebih jauh ke bawah di mana saya mencoba untuk menampilkan variabel menggunakan { this.state.items}. JSON.stringify memperbaikinya!
RubberDuckRabbit
Untuk pembaca masa depan: Tidak, jangan mengonversi ke string. Lakukan ini sebagai gantinya: const Lcomponent = this.wh whateverReturnsObject (); lalu di render () {return <Lcomponent />} Itulah.
Nick
102

Jadi saya mendapatkan kesalahan ini ketika mencoba menampilkan createdAtproperti yang merupakan objek Date. Jika Anda .toString()menyambung di akhir seperti ini, itu akan melakukan konversi dan menghilangkan kesalahan. Hanya memposting ini sebagai jawaban yang mungkin jika ada orang lain yang mengalami masalah yang sama:

{this.props.task.createdAt.toString()}
Brett84c
sumber
2
Bingo! Saya punya masalah ini tetapi terlempar keluar jalur karena meja yang menampilkannya akan memuat (dan memuat ulang) dengan baik. Bereaksi hanya akan membuang objects are not validpelanggaran invarian ketika saya menambahkan baris. Ternyata saya mengonversi objek Date () ke string sebelum bertahan sehingga hanya baris baru saya yang memiliki objek untuk tanggal yang dibuat. :( Belajar dari orang-orang teladan saya yang bandel!
Steve
37

Saya baru saja mendapatkan kesalahan yang sama tetapi karena kesalahan yang berbeda: Saya menggunakan kawat gigi ganda seperti:

{{count}}

untuk memasukkan nilai countbukannya yang benar:

{count}

dimana kompiler mungkin berubah menjadi {{count: count}}, yaitu mencoba memasukkan Obyek sebagai anak Bereaksi.

Dogbert
sumber
3
apa {{}} dimaksudkan untuk /
Muneem Habib
4
@MuneemHabib itu hanya sintaks ES6. Bereaksi membutuhkan sepasang {}. Pasangan batin diperlakukan sebagai kode ES6. Dalam ES6, {count}sama dengan {count: count}. Jadi ketika Anda mengetik {{count}}, itu persis sama dengan { {count: count} }.
Dogbert
1
Apakah kesalahan ini - ini masalahnya. Dalam menetapkan variabel saya untuk menyatakan dalam konstruktor yang saya miliki this.state = {navMenuItems: {navMenu}};... yang pada dasarnya mengubah JSX saya navMenumenjadi objek generik. Mengubah untuk this.state = {navMenuItems: navMenu};menyingkirkan 'pemeran' yang tidak disengaja Objectdan memperbaiki masalah tersebut.
lowcrawler
30

Hanya berpikir saya akan menambah ini karena saya memiliki masalah yang sama hari ini, ternyata itu karena saya hanya mengembalikan fungsinya, ketika saya membungkusnya dengan <div>tag, ia mulai bekerja, seperti di bawah ini

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

Di atas menyebabkan kesalahan. Saya memperbaiki masalah dengan mengubah return()bagian menjadi:

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

... atau hanya:

return gallerySection
pengguna2997982
sumber
8
atau Anda dapat menggunakan return gallerySectionjika Anda ingin menghindari ekstradiv
Vishal
5
Kembali gallerySectionbukannya <div>{gallerySection}</div>membantu saya.
Zanon
16

Bereaksi anak (tunggal) harus tipe tipe data primitif bukan objek atau bisa juga tag JSX (yang tidak ada dalam kasus kami) . Gunakan paket Proptypes dalam pengembangan untuk memastikan validasi terjadi.

Hanya perbandingan potongan kode singkat (JSX) untuk mewakili Anda dengan ide:

  1. Kesalahan: Dengan objek yang diteruskan ke anak

    <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. Tanpa kesalahan: Dengan properti objek ( yang harus primitif, yaitu nilai string atau nilai integer ) diteruskan ke child.

    <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; (Dari sumber di bawah): Pastikan semua item yang Anda render di BEJ adalah primitif dan bukan objek saat menggunakan Bereaksi. Kesalahan ini biasanya terjadi karena fungsi yang terlibat dalam pengiriman peristiwa telah diberi jenis objek yang tidak terduga (yaitu melewati objek ketika Anda harus melewati sebuah string) atau bagian dari JSX di komponen Anda tidak merujuk ke primitif (mis. This.props vs this.props.name).

Sumber - codingbismuth.com

Temui Zaveri
sumber
2
tautan ini tidak lagi berfungsi, namun saya menemukan struktur jawaban Anda yang paling informatif dalam kasus penggunaan saya. Kesalahan ini dapat diproduksi di kedua web dan bereaksi lingkungan asli, dan sering terjadi sebagai kesalahan siklus ketika mencoba untuk .map () array objek dalam komponen menggunakan siklus hidup async. Saya menemukan utas ini saat menggunakan reaksi asli-asli-scrollview
mibbit
Senang, Anda menemukannya bermanfaat dan terima kasih telah menandai masalah tautan.
Temui Zaveri
1
Ini membantu saya. Kembalikan properti daripada objek:return <p>{item.whatever}</p>;
Chris
15

Milik saya harus dilakukan dengan tidak perlu menempatkan kurung kurawal di sekitar variabel yang memegang elemen HTML di dalam pernyataan kembali fungsi render (). Ini membuat React memperlakukannya sebagai objek daripada elemen.

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

  return (
    {element}
  )
}

Setelah saya menghapus kurung kurawal dari elemen, kesalahan itu hilang, dan elemen itu diberikan dengan benar.

Liran H
sumber
Terima kasih! Hapus kurung kurawal dari elemen bekerja untuk saya juga!
Hua Zhang
12

Tambang saya lakukan dengan melupakan kawat gigi keriting di sekitar alat peraga yang dikirim ke komponen presentasi:

Sebelum:

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

Setelah

const TypeAheadInput = ({name, options, onChange, value, error}) => {
steveareeno
sumber
1
Masalah saya paling mirip dengan Anda, jadi menerapkan solusi Anda membantu saya. +1 dan Terima kasih!
m1gp0z
9

Saya juga mendapatkan kesalahan "Objek tidak valid sebagai anak Bereaksi" dan bagi saya penyebabnya adalah karena memanggil fungsi asinkron di JSX saya. Lihat di bawah.

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

Apa yang saya pelajari adalah bahwa rendering asinkron tidak didukung dalam Bereaksi. Tim Bereaksi sedang mengerjakan solusi seperti yang didokumentasikan di sini .

Ken A Collins
sumber
apa yang seharusnya Anda lakukan adalah memperbarui status saat data masuk, dan kemudian merender komponen menggunakan nilai status
mrwagaba
apa yang seharusnya Anda lakukan adalah memperbarui status saat data masuk, dan kemudian merender komponen menggunakan nilai status
mrwagaba
7

Bagi siapa pun yang menggunakan Firebase dengan Android, ini hanya merusak Android. Emulasi iOS saya mengabaikannya.

Dan seperti yang diposting oleh Apoorv Bankey di atas.

Apa pun di atas Firebase V5.0.3, untuk Android, atm adalah sebuah kegagalan. Memperbaiki:

npm i --save firebase@5.0.3

Dikonfirmasi berkali-kali di sini https://github.com/firebase/firebase-js-sdk/issues/871

RedEarth
sumber
Bagi siapa pun yang mencoba solusi yang diusulkan oleh KNDheeraj di bawah ini, **** 1 down vote Jika Anda menggunakan Firebase, maka salah satu file dalam proyek Anda. Maka cukup tempatkan pernyataan firebase impor itu di akhir !! Saya tahu ini terdengar gila tetapi cobalah !! **************** Saya memang mencobanya dan ini bukan solusi untuk iOS tetapi untuk Android pada Windows saja.
RedEarth
6

Saya juga memiliki masalah yang sama tetapi kesalahan saya sangat bodoh. Saya mencoba mengakses objek secara langsung.

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

}
Nimmi Verma
sumber
4

Jika karena alasan tertentu Anda mengimpor firebase. Lalu cobalah berlari npm i --save [email protected]. Ini karena firebase break react-native, jadi menjalankan ini akan memperbaikinya.

Apoorv Bankey
sumber
3

Dalam kasus saya, saya lupa mengembalikan elemen html dari fungsi render dan saya mengembalikan sebuah objek. Apa yang saya lakukan adalah saya baru saja membungkus {items} dengan elemen html - div sederhana seperti di bawah ini

<ul>{items}</ul>

Shan
sumber
3

Saya memiliki masalah yang sama karena saya tidak memasukkan propskurung kurawal.

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

Jadi jika kode Anda mirip dengan yang di atas maka Anda akan mendapatkan kesalahan ini. Untuk mengatasinya cukup letakkan kurung kurawal di sekitar props.

export default function Hero({ children, hero }) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}
Suresh Mangs
sumber
@Dharman Saya pikir ini dipahami dengan baik bahkan sebelum lekukan kecil ini
Suresh Mangs
Saya tidak mengatakan itu bukan. Saya pikir jawaban Anda terlihat lebih baik dengan lekukan. Jika Anda tidak setuju, silakan memutar kembali.
Dharman
3

Saya mendapat kesalahan yang sama, saya mengubah ini

export default withAlert(Alerts)

untuk ini

export default withAlert()(Alerts).

Di versi yang lebih lama, kode yang lama tidak masalah, tetapi di versi yang lebih lama kode itu melempar kesalahan. Jadi gunakan kode yang lebih baru untuk menghindari kesalahan.

Shubham Patil
sumber
3

Dalam kasus saya kesalahan terjadi karena saya mengembalikan elemen array di kurung kurawal bukan hanya mengembalikan array itu sendiri.

Kode dengan kesalahan

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

Kode yang benar

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

Anda hanya menggunakan kunci objek, bukan seluruh objek!

Rincian lebih lanjut dapat ditemukan di sini: 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>

Cody Grey
sumber
2

Saya memiliki masalah yang sama, dalam kasus saya, saya memperbarui redux keadaan , dan parameter data baru tidak cocok dengan parameter lama, Jadi ketika saya ingin mengakses beberapa parameter melalui Kesalahan ini,

Mungkin pengalaman ini membantu seseorang

Mohammad Masoumi
sumber
Dalam kasus saya, (Django) ListSerializer dan CreateSerializer mengembalikan bidang yang sama dan beberapa di antaranya (terserah proyek Anda) hanya bidang baca-saja, Jadi ambil Sekali dan kapan pun membuat data baru cukup perbarui redux state
Mohammad Masoumi
2

Jika Anda menggunakan Firebase dan melihat kesalahan ini, ada baiknya untuk memeriksa apakah Anda mengimpornya dengan benar. Pada versi 5.0.4 Anda harus mengimpornya seperti ini:

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

Ya saya tahu. Saya kehilangan 45 menit untuk ini juga.

Lucas Bustamante
sumber
Terima kasih. Itu memecahkan masalah saya dengan firebase (5.9.2) :)
Mate
2

Biasanya ini muncul karena Anda tidak merusak dengan benar. Ambil kode ini misalnya:

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

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

Kami mendeklarasikannya dengan = text =>param. Tapi sungguh, React mengharapkan ini menjadi propsobjek yang mencakup semua .

Jadi kita harus benar-benar melakukan sesuatu seperti ini:

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

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

Perhatikan perbedaannya? The propsparam sini bisa diberi nama apa saja (props hanya konvensi yang cocok nomenklatur), bereaksi hanya mengharapkan sebuah objek dengan tombol dan vals.

Dengan perusakan objek yang dapat Anda lakukan, dan akan sering melihat, sesuatu seperti ini:

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

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

... yang berhasil.

Kemungkinannya, siapa pun yang menemukan ini hanya secara tidak sengaja menyatakan alat peraga komponen mereka tanpa merusak.

Corysimmons
sumber
1

Saya hanya menempatkan diri saya melalui versi yang sangat konyol dari kesalahan ini, yang mungkin saya bagikan di sini untuk anak cucu.

Saya punya beberapa BEJ seperti ini:

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

Saya perlu mengomentari ini untuk men-debug sesuatu. Saya menggunakan pintasan keyboard di IDE saya, yang menghasilkan ini:

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

Yang, tentu saja, tidak valid - objek tidak valid sebagai reaksi anak-anak!

shab
sumber
1

Saya ingin menambahkan solusi lain ke daftar ini.

Spesifikasi:

  • "reaksi": "^ 16.2.0",
  • "react-dom": "^ 16.2.0",
  • "react-redux": "^ 5.0.6",
  • "script reaksi": "^ 1.0.17",
  • "redux": "^ 3.7.2"

Saya mengalami kesalahan yang sama:

Kesalahan Tidak Tertangkap: Objek tidak valid sebagai anak Bereaksi (ditemukan: objek dengan kunci {XXXXX}). Jika Anda bermaksud membuat koleksi anak-anak, gunakan array.

Ini adalah kode saya:

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

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

Larutan:

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

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

Masalahnya terjadi karena muatan mengirim barang sebagai objek. Ketika saya menghapus variabel payload dan memasukkan nilai userInput ke dalam pengiriman semuanya mulai berfungsi seperti yang diharapkan.

bprdev
sumber
1

Jika seandainya Anda menggunakan Firebase salah satu file dalam proyek Anda. Maka cukup tempatkan pernyataan firebase impor itu di akhir !!

Saya tahu ini terdengar gila tetapi cobalah !!

KNDheeraj
sumber
1

Masalah saya sederhana ketika saya menghadapi kesalahan berikut:

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

hanya saja saya melewatkan objek dengan kunci yang ditentukan dalam kesalahan saat mencoba untuk merender objek secara langsung dalam komponen menggunakan {objek} mengharapkannya menjadi string

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

saat merender pada Komponen Bereaksi, saya menggunakan sesuatu seperti di bawah ini

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

tapi seharusnya begitu

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

Jika menggunakan komponen stateless, ikuti format seperti ini:

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

Ini sepertinya bekerja untuk saya

ppak10
sumber
1

Sesuatu seperti ini baru saja terjadi pada saya ...

Saya menulis:

{response.isDisplayOptions &&
{element}
}

Menempatkannya di dalam div memperbaikinya:

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

Ditemukan: objek dengan kunci

Yang berarti Anda melewati sesuatu adalah nilai kunci. Jadi, Anda perlu memodifikasi handler Anda:

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

Anda melewatkan kawat gigi ( {}).

Arul Mani
sumber
1
tidak percaya ini masalahnya
kushal.8
Saya juga heran. masih belum mencari tahu apa masalah yang menyebabkan ini
Arul Mani
1

Dalam kasus saya, saya menambahkan async ke komponen fungsi anak saya dan mengalami kesalahan ini. Jangan gunakan async dengan komponen anak.

Tolga
sumber
0

Jika menggunakan Firebase, jika itu tidak berhasil dengan meletakkan di akhir importpernyataan maka Anda bisa mencoba memasukkannya ke dalam salah satu metode siklus-hidup, yaitu, Anda bisa memasukkannya ke dalam componentWillMount().

componentWillMount() {
    const firebase = require('firebase');
    firebase.initializeApp({
        //Credentials
    });
}
Germa Vinsmoke
sumber
0

Invariant Violation: Objects are not valid as a React childterjadi pada saya ketika menggunakan komponen yang membutuhkan renderItemalat peraga, seperti:

renderItem={this.renderItem}

dan kesalahan saya adalah membuat renderItemmetode saya async.

vmarquet
sumber
0

Kesalahan saya adalah karena menulis seperti ini:

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



dari pada:

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

Itu berarti saya mencoba untuk membuat objek, bukan nilai di dalamnya.

sunting: ini untuk bereaksi bukan asli.

Deke
sumber