不変の違反:オブジェクトはReactの子としては無効です


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>要素をクリックすると、次のエラーが表示されます。

キャッチされないエラー:不変の違反:オブジェクトはReactの子として有効ではありません(見つかった:キー{dispatchConfig、dispatchMarker、nativeEvent、target、currentTarget、type、eventPhase、bubbles、cancellable、timeStamp、defaultPrevented、isTrusted、view、detail、screenXを持つオブジェクト、screenY、clientX、clientY、ctrlKey、shiftKey、altKey、metaKey、getModifierState、button、buttons、relatedTarget、pageX、pageY、isDefaultPrevented、isPropagationStopped、_dispatchListeners、_dispatchIDs})。子のコレクションをレンダリングする場合は、代わりに配列を使用するか、ReactアドオンのcreateFragment(object)を使用してオブジェクトをラップしてください。のレンダリング方法を確認してくださいWelcome

map関数の内部に変更するthis.onItemClick.bind(this, item)(e) => onItemClick(e, item)、すべてが期待どおりに機能します。

誰かが私が間違っていることを説明し、なぜこのエラーが発生するのかを説明できれば、すばらしいでしょう

更新1:
onItemClick関数は次のとおりであり、this.setStateを削除するとエラーが消えます。

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

しかし、このコンポーネントの状態を更新する必要があるため、この行を削除することはできません


2
それでは、どのようthis.onItemClickに実装されますか?
zerkms 2015年

@zerkms返信いただきありがとうございます。質問を更新しました。そうです、問題はthis.setState()にあるようですが、なぜこのエラーがスローされるのですか?:(
almeynman、2015年

setStateに構文エラーはありますか?余分なコンマ?エラーは修正されない可能性がありますが、見つかっただけです。
Bhargav Ponnapalli 2015年

@bhargavponnapalliカンマは好みの問題であり、私のエスリントはそれを強制するが、それを削除しても役に立たない
-almeynman

リファクタリングで状態に追加した後、ローカル変数からステートフルオブジェクトになった変数を中括弧で囲むのを忘れたときに、このエラーが発生しました。
jamescampbell、

回答:


398

このエラーが発生しましたが、文字列値であると予期していたJSXコードに誤ってオブジェクトを含めていたことがわかりました。

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

breadcrumbElement以前は文字列でしたが、リファクタリングによりオブジェクトになりました。残念ながら、Reactのエラーメッセージは、問題が存在する行を指摘するのに適切ではありませんでした。「小道具」がコンポーネントに渡されていることに気づき、問題のコードが見つかるまで、スタックトレースをたどる必要がありました。

文字列値であるオブジェクトのプロパティを参照するか、オブジェクトを望ましい文字列表現に変換する必要があります。1つのオプションはJSON.stringify、実際にオブジェクトの内容を見たい場合です。


13
では、オブジェクトがある場合、それを望ましいものに変換するにはどうすればよいでしょうか?
adinutzyc21 2016年

4
文字列値であるオブジェクトのプロパティを参照するか、オブジェクトを望ましい文字列表現に変換する必要があります。オブジェクトのコンテンツを実際に表示したい場合、1つのオプションはJSON.stringifyです。
コードコマンダー、

2
同じエラーが発生し、この説明で問題が解決しました。これのために1 UP。:)
papski 2018年

ああ、私は間違った行を指しているエラーメッセージの同じ問題がありました-それは本当にエラーがthis.setState({items:items})にあると言いました。 this.state.items}。JSON.stringifyで修正しました!
RubberDuckRabbit

今後の読者向け:いいえ、文字列に変換しないでください。代わりにこれを行ってください:const Lcomponent = this.whateverReturnsObject(); その後、render(){return <Lcomponent />}でそのとおりです。
Nick

102

そのcreatedAtため、Dateオブジェクトであるプロパティを表示しようとすると、このエラーが発生しました。.toString()このように最後に連結すると、変換が行われ、エラーが解消されます。他の誰かが同じ問題に遭遇した場合に備えて、これを可能な回答として投稿するだけです:

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

2
ビンゴ!私はこの問題を抱えていましたが、それを表示していたテーブルが正常にロード(およびリロード)するため、トラックから外れました。行objects are not valid追加したときにのみ、Reactは不変違反をスローします。永続化する前にDate()オブジェクトを文字列に変換していたため、新しい行にのみ作成日のオブジェクトが含まれていることがわかりました。:(私のわがままな例の人々から学んでください!
スティーブ

37

同じエラーが発生しましたが、別の間違いが原因でした。

{{count}}

count正しい値の代わりにの値を挿入するには:

{count}

コンパイラはおそらくに変わりました{{count: count}}。つまり、オブジェクトをReactの子として挿入しようとしています。


3
{{}}の意味/
Muneem Habib

4
@MuneemHabibそれは単にES6構文です。Reactには1組のが必要です{}。内側のペアはES6コードとして扱われます。ES6では{count}、と同じ{count: count}です。したがって、と入力する{{count}}と、とまったく同じになり{ {count: count} }ます。
Dogbert 2017

1
このエラーが発生しました-これが問題でした。変数をコンストラクターの状態に割り当てる際に、this.state = {navMenuItems: {navMenu}};基本的にJSX navMenuを汎用オブジェクトに変換しました。変更this.state = {navMenuItems: navMenu};への意図的でない「キャスト」を処分したObjectと問題を修正しました。
ロークローラ2018

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 2017

5
gallerySection代わりに戻っ<div>{gallerySection}</div>て私を助けました。
Zanon

16

React子(単数)は、オブジェクトではなくプリミティブデータ型のタイプである必要があります。そうでない場合は、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; (以下のソースから):Reactを使用する場合は、JSXでレンダリングするすべてのアイテムがプリミティブであり、オブジェクトではないことを確認してください。このエラーは通常、イベントのディスパッチに関係する関数に予期しないオブジェクトタイプ(文字列を渡す必要があるときにオブジェクトを渡す)が指定されているか、コンポーネントのJSXの一部がプリミティブを参照していないために発生します(つまりthis.props vs this.props.name)。

ソース-codingbismuth.com


2
このリンクは機能しなくなりましたが、私はあなたの回答の構造が私のユースケースで最も有益であると思います。このエラーは、Web環境と反応ネイティブ環境の両方で発生し、非同期ライフサイクルを使用してコンポーネント内のオブジェクトの配列を.map()しようとすると、ライフサイクルエラーとして発生することがよくあります。reactネイティブreact-native-scrollviewを使用しているときにこのスレッドに出くわしました
mibbit

リンクの問題を報告していただきありがとうございます。
Zaveri 2019年

1
これは私を助けました。オブジェクトではなくプロパティを返す:return <p>{item.whatever}</p>;
Chris

15

鉱山は、render()関数のreturnステートメント内のHTML要素を保持する変数の周りに不必要に中括弧を置くことと関係がありました。これにより、Reactはそれを要素ではなくオブジェクトとして扱いました。

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

  return (
    {element}
  )
}

中括弧を要素から削除すると、エラーはなくなり、要素は正しくレンダリングされました。


ありがとう!要素から中かっこを削除することもできます。
Hua Zhang

12

鉱山は、プレゼンテーションコンポーネントに送信される小道具の周りの中括弧を忘れることに関係していました。

前:

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

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

1
私の問題はあなたの問題に最も似ていたので、あなたの解決策を適用することが私を助けました。+1とありがとう!
m1gp0z

9

私もこの「オブジェクトはReactの子として有効ではありません」というエラーを受け取りましたが、原因は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チームは、ここに記載されている解決策に取り組んでいます


代わりに、データが入ってくるときに状態を更新し、状態値を使用してコンポーネントをレンダリングする必要があります
mrwagaba

代わりに、データが入ってくるときに状態を更新し、状態値を使用してコンポーネントをレンダリングする必要があります
mrwagaba

7

AndroidでFirebaseを使用している人にとっては、これはAndroidを壊すだけです。私のiOSエミュレーションはそれを無視します。

上記のApoorv Bankeyによる投稿。

Firebase V5.0.3を超えるものはすべて、Androidではatmが破綻します。修正:

npm i --save firebase@5.0.3

ここで何度も確認 https://github.com/firebase/firebase-js-sdk/issues/871


以下のKNDheerajによって提案された解決策を試みる誰にとっても、**** 1の反対票Firebaseを使用している場合、プロジェクト内のいずれかのファイル。次に、そのインポートfirebaseステートメントを最後に配置するだけです!! クレイジーに聞こえますが、試してみてください!! ****************私は試しましたが、これはiOS向けのソリューションではなく、Windows上のAndroid向けのソリューションです。
RedEarth 2018

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

私の場合は、render関数からhtml要素を返すのを忘れていて、オブジェクトを返していました。私がしたことは、{items}をhtml要素でラップしただけです-以下のような単純なdiv

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

@ダーマン私はこれがこの小さなインデントの前でもよく理解されていたと思います
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/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

私は同じ問題を抱えています、私の場合、私はreduxを更新します状態新しいデータパラメーターが古いパラメーターと一致しませんでした。

多分この経験は誰かを助ける


私の場合、(Django)ListSerializerとCreateSerializerは同じフィールドを返し、それらの一部(プロジェクト次第)は読み取り専用フィールドです。したがって、一度フェッチするだけで、新しいデータを作成するだけで、redux状態を更新するだけです
Mohammad Masoumi

2

Firebaseを使用していてこのエラーが表示される場合は、正しくインポートしているかどうかを確認することをお勧めします。バージョン5.0.4以降、次のようにインポートする必要があります。

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

はい、知っています。これも45分負けました。


ありがとうございました。Firebase(5.9.2)に関する私の問題を解決しました:)
メイト

2

通常、これは、適切に分解しないために発生します。たとえば、次のコードを見てください。

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

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

これを= text =>paramで宣言しています。しかし、実際には、Reactはこれがすべてを包括することを期待していますpropsオブジェクトであるます。

したがって、実際には次のようにする必要があります。

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

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

違いに気づきましたか?ここでのpropsパラメータは任意の名前にすることができます(props命名法と一致しただけの慣習です)、単にキーとヴァルス持つオブジェクトを期待して反応します。

オブジェクトの分解により、次のようなことが可能になり、頻繁に表示されます。

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

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

...うまくいきます。

偶然、これに偶然出くわした人は、破壊せずに誤ってコンポーネントのプロップパラメータを宣言しただけです。


1

私はこのエラーの本当にばかげたバージョンを自分で試してみました。後世のためにここで共有することもできます。

私はこのようなJSXをいくつか持っていました:

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

何かをデバッグするには、これをコメント化する必要がありました。IDEでキーボードショートカットを使用した結果、次のようになりました。

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

もちろん、これは無効です-オブジェクトは子供たちの反応として有効ではありません!


1

このリストに別のソリューションを追加したいと思います。

スペック:

  • "反応する": "^ 16.2.0"、
  • "反応-dom": "^ 16.2.0"、
  • "react-redux": "^ 5.0.6"、
  • "反応スクリプト": "^ 1.0.17"、
  • "redux": "^ 3.7.2"

同じエラーが発生しました:

キャッチされないエラー:オブジェクトはReactの子としては無効です(見つかった:キー{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

見つかった:キーを持つオブジェクト

つまり、何かを渡すことはKey-Valueです。したがって、ハンドラーを変更する必要があります。

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

中括弧({})を省略しました。


1
これが問題だったとは信じられません
kushal.8

私も不思議です。どのような問題が原因であるかはまだ
わかり

1

私の場合、子関数コンポーネントに非同期を追加したところ、このエラーが発生しました。子コンポーネントで非同期を使用しないでください。


0

Firebaseを使用している場合、importステートメントの最後に配置しても機能しない場合は、ライフサイクルメソッドの1つに配置することができます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>)
})

それは私がその中の値の代わりにオブジェクトをレンダリングしようとしていたことを意味しました。

編集:これはネイティブではなく反応のためのものです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.