Değişmez İhlal: Nesneler Tepki alt öğesi olarak geçerli değil


337

Bileşenimin render işlevinde:

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

her şey iyi işliyor, ancak <li>öğeyi tıklattığınızda aşağıdaki hatayı alıyorum:

Yakalanmayan Hata: Değişmez İhlal: Nesneler bir Reaksiyon alt öğesi olarak geçerli değil (bulunan: {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, type, eventPhase, bubbles, iptal edilebilir, timeStamp, defaultPrevented, isTrusted, view, detail, screenX anahtarlarına sahip nesne , screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, düğme, düğmeler, relatedTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}). Bir alt koleksiyon oluşturmak istiyorsanız, bunun yerine bir dizi kullanın ya da React eklentilerinden createFragment (object) kullanarak nesneyi sarın. İşleme yöntemini kontrol edin Welcome.

Ben geçerseniz this.onItemClick.bind(this, item)için (e) => onItemClick(e, item)harita işlevi her şeyi eserleri içine beklendiği gibi.

Birisi neyi yanlış yaptığımı açıklayabilir ve neden bu hatayı alıyorum?

GÜNCELLEME 1:
onItemClick işlevi aşağıdaki gibidir ve this.setState kaldırıldığında hata kaybolur.

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

Ancak bu bileşenin durumunu güncellemem gerektiğinden bu satırı kaldıramıyorum


2
Peki nasıl this.onItemClickuygulanır?
zerkms

@zerkms Yanıtladığınız için teşekkür ederiz, soruyu güncelledim ve evet, sorunun this.setState () içinde olduğu anlaşılıyor, ancak neden bu hatayı atıyor? :(
almeynman

SetState sözdizimi hatası var mı? Fazladan virgül mü? Hatayı düzeltebilir, ancak bulmuş olabilir.
Bhargav Ponnapalli

@bhargavponnapalli virgül bir tercih meselesidir, eslintim bunu yapmaya zorlar, ancak kaldırmak yardımcı olmaz, cevap için teşekkürler
almeynman

Refactor içinde duruma ekledikten sonra yerel değişken bir durum ful nesnesi haline gelmiş bir değişken etrafında kıvırcık parantez unuttum bu hatayı aldım.
jamescampbell

Yanıtlar:


398

Bu hatayı alıyordum ve yanlışlıkla bir dize değeri olması beklenen benim JSX kodunda bir nesne dahil olduğu ortaya çıktı:

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

breadcrumbElementeskiden bir dize olurdu ama bir refactor nedeniyle bir Nesne haline gelmişti. Ne yazık ki, React'ın hata mesajı beni sorunun var olduğu çizgiye işaret etmede iyi bir iş yapmadı. Ben bir bileşen içine "sahne" tanınan ve sonra rahatsız edici kodu bulundu kadar tanıma kadar benim yığın izini takip etmek zorunda kaldı.

Nesnenin dize değeri olan bir özelliğine başvurmanız veya Nesneyi istenen bir dize temsiline dönüştürmeniz gerekir. JSON.stringifyNesnelerin içeriğini gerçekten görmek istiyorsanız bir seçenek olabilir .


13
Öyleyse, bir nesneniz varsa, onu istenen bir şeye dönüştürmeye nasıl devam edersiniz?
adinutzyc21

4
Nesnenin dize değeri olan bir özelliğine başvurmanız veya Nesneyi istenen bir dize temsiline dönüştürmeniz gerekir. Nesnenin içeriğini gerçekten görmek istiyorsanız bir seçenek JSON.stringify olabilir.
Kod Komutanı

2
Aynı hatayla karşılaştım ve bu açıklama sorunumu çözdü. Bunun için 1 UP. :)
papski

Ahh, yanlış satıra işaret eden hata mesajında ​​da aynı sorunu yaşadım - hatayı { this.state.items}. JSON.stringify düzeltildi!
RubberDuckRabbit

Gelecekteki okuyucular için: Hayır dizeye dönüştürmeyin. Bunun yerine şunu yapın: const Lcomponent = this.whateverReturnsObject (); sonra render () {return <Lcomponent />} İşte bu.
Nick

102

createdAtBir Date nesnesi olan özelliği görüntülemeye çalışırken bu hatayı aldım . .toString()Sonunda böyle birleştirirseniz , dönüştürme işlemi yapar ve hatayı ortadan kaldırır. Başka birinin aynı problemle karşılaşması durumunda bunu olası bir cevap olarak yayınlamanız yeterlidir:

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

2
Bingo! Ben bu sorunu vardı ama görüntülenen tablo (ve yeniden yüklemek) gayet iyi olurdu çünkü parça atılır. Tepki, objects are not validdeğişmez ihlali yalnızca bir satır eklediğimde atacaktı . Date () nesnesini devam ettirmeden önce bir dizeye dönüştürdüğüm anlaşılıyor, bu yüzden yalnızca yeni satırlarım oluşturulan tarih için nesneler vardı. :( Doğru örnek insanlardan öğrenin!
Steve

37

Ben sadece aynı hatayı aldım ama farklı bir hata nedeniyle: gibi çift parantez kullandım:

{{count}}

countdoğru yerine değeri eklemek için :

{count}

derleyicinin büyük olasılıkla dönüştürdüğü {{count: count}}, yani bir Nesneyi Reaksiyon alt öğesi olarak eklemeye çalıştığı.


3
{{}} ne anlama gelir? /
Muneem Habib

4
@MuneemHabib sadece ES6 sözdizimi. Tepkinin bir çiftine ihtiyacı var {}. İç çift ES6 kodu olarak kabul edilir. ES6'da {count}ile aynıdır {count: count}. Yani yazdığınızda {{count}}, bu tam olarak aynıdır { {count: count} }.
Dogbert

1
Bu hata vardı - bu sorun oldu. Değişkeni yapıcıdaki duruma atayarak this.state = {navMenuItems: {navMenu}};... temelde JSX'imi navMenugenel bir nesneye dönüştürdüm. Değişen this.state = {navMenuItems: navMenu};hiç kasıtsız 'döküm' kurtulduk Objectve sorunu giderdik.
lowcrawler

30

Sadece bugün aynı sorunu yaşadığım için buna ekleyeceğimi düşündüm, bunun nedeni sadece işlevi döndürdüğüm için ortaya çıktı, bir <div>etikete sardığımda çalışmaya başladı, aşağıdaki gibi

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

Yukarıdaki hataya neden oldu. return()Bölümü şu şekilde değiştirerek sorunu giderdim :

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

...ya da sadece:

return gallerySection

8
ya da return gallerySectionfazladan kaçınmak istiyorsanız kullanabilirsinizdiv
Vishal

5
Geri dönen gallerySectionyerine <div>{gallerySection}</div>bana yardımcı oldu.
Zanon

16

Tepki alt öğesi (tekil) , nesne değil ilkel veri türü olmalıdır veya JSX etiketi olabilir (bu bizim durumumuzda değildir) . Doğrulamanın gerçekleştiğinden emin olmak için geliştirmede Proptypes paketini kullanın.

Sizi fikirle temsil etmek için bir hızlı kod snippet (JSX) karşılaştırması:

  1. Hata: Nesnenin alt öğeye geçirilmesi

    <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. Hatasız: Nesnenin özelliği ( ilkel, yani bir dize değeri veya tamsayı değeri olmalıdır ) alt öğeye iletildiğinde.

    <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; (Aşağıdaki kaynaktan): React kullanırken JSX'te oluşturduğunuz tüm öğelerin ilkel olduğundan ve nesne olmadığından emin olun. Bu hata genellikle, bir olayı göndermeyle ilgili bir işleve beklenmeyen bir nesne türü verildiğinden (yani, bir dizeyi geçirmeniz gerektiğinde bir nesneyi iletme) veya bileşeninizdeki JSX'in bir kısmına ilkel (yani this.props) başvurmadığı için oluşur. vs this.props.name).

Kaynak - codingbismuth.com


2
Bu bağlantı artık çalışmıyor, ancak yanıtınızın yapısını kullanım durumumdaki en bilgilendirici buluyorum. Bu hata hem web'de hem de yerel ortamlarda tepki verirken üretilebilir ve genellikle zaman uyumsuz yaşam döngüsü kullanan bir bileşen içindeki bir nesne dizisini .map () denerken bir yaşam döngüsü hatası olarak ortaya çıkar. Tepki yerli tepki-yerli-
scrollview

Sevindim, yararlı bulduğunuz ve bağlantı sorununu işaretlediğiniz için teşekkürler.
Zaveri ile tanışın

1
Bu bana yardımcı oldu. Nesne yerine bir mülk getirin:return <p>{item.whatever}</p>;
Chris

15

Mine, render () işlevinin return deyiminin içinde bir HTML öğesini tutan bir değişkenin etrafına kıvırcık parantez koymakla ilgiliydi. Bu React'i bir elemandan ziyade bir nesne olarak ele aldı.

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

  return (
    {element}
  )
}

Kıvrık parantezleri elemandan çıkardığımda hata gitti ve eleman doğru bir şekilde oluşturuldu.


Teşekkürler! Kıvırcık parantez kaldırmak benim için de eleman çalışır!
Hua Zhang

12

Benim sunumun bileşenine gönderilen sahne etrafındaki kıvırcık parantezleri unutmakla ilgisi vardı:

Önce:

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

Sonra

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

1
Benim sorunum sizinkine çok benziyordu, bu yüzden çözümünüzü uygulamak bana yardımcı oldu. +1 ve Teşekkürler!
m1gp0z

9

Ben de bu "Nesneler bir React child olarak geçerli değil" hatası alıyordum ve benim için neden benim JSX zaman uyumsuz bir işlev çağırma nedeniyle oldu. Aşağıya bakınız.

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

Öğrendiğim şey, React'te eşzamansız oluşturmanın desteklenmediğidir. React ekibi burada belgelendiği gibi bir çözüm üzerinde çalışıyor .


Bunun yerine veri
geldikçe

Bunun yerine veri
geldikçe

7

Android ile Firebase kullanan herkes için bu sadece Android'i kırıyor. İOS öykünmem bunu yok sayar.

Ve yukarıda Apoorv Bankey tarafından gönderildi.

Firebase V5.0.3 üzerindeki her şey, Android için atm bir büst. Düzeltme:

npm i --save firebase@5.0.3

Burada defalarca onaylandı https://github.com/firebase/firebase-js-sdk/issues/871


Aşağıda KNDheeraj tarafından önerilen çözümü deneyen herkes için, **** 1 aşağı oy Firebase kullanmanız durumunda projenizdeki herhangi bir dosya varsa. Sonra sadece bu ithalat firebase deyimi sonunda yerleştirin !! Bunun çılgınca geldiğini biliyorum ama deneyin !! **************** Ben denedim ve bu iOS için değil, sadece Windows için Android için bir çözüm.
RedEarth

6

Aynı problemim var ama benim hatam çok aptalca. Nesneye doğrudan erişmeye çalışıyordum.

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

Herhangi bir nedenle firebase ithal ettiyseniz. Ardından koşmayı deneyin npm i --save firebase@5.0.3. Bunun nedeni, yangın tabanının break-native tepkimesi olmasıdır, bu nedenle bunu çalıştırmak sorunu çözecektir.


3

Benim durumumda render fonksiyonu frm bir html öğesi döndürmeyi unuttum ve bir nesne iade edildi. Ne yaptım sadece bir html öğesi ile {items} sarılmış oldu - aşağıdaki gibi basit bir div

<ul>{items}</ul>


3

propsKıvırcık parantez içine koymak vermedi çünkü aynı sorun vardı .

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

Kodunuz yukarıdakine benzer ise, bu hatayı alırsınız. Bu sorunu çözmek için sadece kıvırcık parantez koymak props.

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

@Dharman Bu küçük girintiden önce bile iyi anlaşıldığını düşünüyorum
Suresh Mangs

Ben öyle demedim. Sanırım cevabınız girinti ile daha iyi görünüyor. Kabul etmiyorsanız lütfen geri almaktan çekinmeyin.
Dharman

3

Aynı hatayı aldım, bunu değiştirdim

export default withAlert(Alerts)

buna

export default withAlert()(Alerts).

Eski sürümlerde eski kod iyiydi, ancak sonraki sürümlerde hata veriyor. Hatadan kaçınmak için sonraki kodu kullanın.


3

Benim durumumda hata sadece dizi kendisini döndürme yerine kıvırcık parantez içinde öğeleri dizisi döndü çünkü oluyordu .

Hatalı kod

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

Doğru kod

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

2

Tüm nesne yerine sadece nesnenin anahtarlarını kullanıyordunuz!

Daha fazla ayrıntıyı burada bulabilirsiniz: 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

Aynı sorun var, benim durumumda, redux'u güncelliyorum durumunu ve yeni veri parametreleri eski parametrelerle eşleşmedi, bu yüzden bu parametreden bazı parametrelere erişmek istediğimde,

Belki bu deneyim birine yardım eder


Benim durumumda, (Django) ListSerializer ve CreateSerializer aynı alanları döndürüyor ve bazıları (projenize bağlı) sadece salt okunur alanlar, Yani bir kez getir ve yeni veri oluşturduğunuzda sadece redux durumunu güncelleyin
Mohammad Masoumi

2

Firebase kullanıyorsanız ve bu hatayı görüyorsanız, doğru alıp almadığınızı kontrol etmeye değer. 5.0.4 sürümünden itibaren şu şekilde içe aktarmanız gerekir:

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

Evet biliyorum. Ben de bu konuda 45 dakika kaybettim.


Teşekkür ederim. Firebase (5.9.2) :) ile sorunumu çözdü
Mate

2

Tipik olarak bu ortaya çıkar çünkü doğru şekilde yıkmazsınız. Örneğin bu kodu ele alalım:

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

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

= text =>Param ile ilan ediyoruz . Ama gerçekten, React bunun her şeyi kapsayan bir propsnesne olmasını bekliyor .

Yani gerçekten böyle bir şey yapmalıyız:

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

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

Farkı fark ettiniz mi? Buradaki propsparam herhangi bir şey olarak adlandırılabilir (props sadece isimlendirme ile eşleşen bir konvansiyondur), React sadece bir nesneyi anahtarlar ve valler ile bekliyor.

İle nesne Strüktür kırıcı Eğer böyle bir şey yapabilir ve sık sık göreceksiniz:

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

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

... işe yarıyor.

Muhtemelen, tökezleyen herkes yanlışlıkla bileşenlerinin sahne parametrelerini yıkmadan ilan etti.


1

Kendimi bu hatanın gerçekten aptalca bir versiyonundan geçirdim, burada da gelecek nesiller için paylaşabiliyorum.

Ben böyle bir JSX vardı:

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

Ben bir şey hata ayıklamak için bu yorum gerekiyordu. Bunun sonucunda IDE'mde klavye kısayolunu kullandım:

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

Tabii ki geçersiz - nesneler tepki çocukları olarak geçerli değil!


1

Bu listeye başka bir çözüm daha eklemek istiyorum.

Özellikleri:

  • "tepki": "^ 16.2.0",
  • "tepki-dom": "^ 16.2.0",
  • "tepki-redux": "^ 5.0.6",
  • "tepki-komut dosyaları": "^ 1.0.17",
  • "redux": "^ 3.7.2"

Aynı hatayla karşılaştım:

Yakalanmayan Hata: Nesneler bir Reaksiyon alt öğesi olarak geçerli değil (bulunan: {XXXXX} anahtarlı nesne). Bir çocuk koleksiyonu oluşturmak istiyorsanız bunun yerine bir dizi kullanın.

Bu benim kodum oldu:

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

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

Çözüm:

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

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

Yük, öğeyi nesne olarak gönderdiğinden sorun oluşuyordu. Yük değişkenini kaldırdım ve userInput değerini gönderime koyduğumda her şey beklendiği gibi çalışmaya başladı.


1

Firebase'i kullanmanız durumunda projenizdeki dosyalardan herhangi biri. Sonra sadece bu ithalat firebase deyimi sonunda yerleştirin !!

Bunun çılgınca geldiğini biliyorum ama denemek !!


1

Aşağıdaki hatayla karşılaştığımda sorunum basitti:

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

sadece bir nesne içinde bir dize olmasını beklerken {object} kullanarak nesneyi doğrudan bir bileşende oluşturmaya çalışırken hatada belirtilen anahtarları olan bir nesneyi geçiriyordum

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

React Bileşeni üzerinde oluşturma yaparken aşağıdaki gibi bir şey kullandım

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

ama olmalıydı

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

1

Durum bilgisi olmayan bileşenler kullanıyorsanız, bu tür biçimi izleyin:

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

Bu benim için çalışıyor gibiydi


1

Böyle bir şey başıma geldi ...

Yazdım:

{response.isDisplayOptions &&
{element}
}

Bir div içine yerleştirerek sabitledi:

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

1

Bulunan: anahtarlı nesne

Bu da bir şeyi geçtiğinizde anahtar / değer çifti olduğudur. Bu yüzden işleyicinizi değiştirmeniz gerekir:

itibaren
onItemClick(e, item) {
   this.setState({
     lang: item,
   });
}
için
onItemClick({e, item}) {
  this.setState({
    lang: item,
  });
}

Diş tellerini ( {}) kaçırdınız .


1
sorunun olduğuna inanamıyorum
kushal.8

ben de merak ediyorum. Hala bu sorunun ne olduğunu anlayamadım
Arul Mani

1

Benim durumumda, alt işlev bileşenime bir zaman uyumsuzluk ekledim ve bu hatayla karşılaştım. Alt bileşenle asenkron kullanmayın.


0

Firebase kullanıldığında, importifadelerin sonuna koyarak işe yaramazsa, bunu yaşam döngüsü yöntemlerinden birine koymaya çalışabilirsiniz, yani içine koyabilirsiniz componentWillMount().

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

0

Invariant Violation: Objects are not valid as a React childbir renderItemsahne gerektiren bir bileşen kullanılırken başıma geldi , örneğin:

renderItem={this.renderItem}

ve benim hatam renderItemyöntemimi yapmaktı async.


0

Benim hatam, bu şekilde yazma nedeniyle oldu:

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



onun yerine:

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

Bu, içindeki değer yerine nesne oluşturmaya çalıştığım anlamına geliyordu.

edit: bu yerli tepki değil.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.