web-dev-qa-db-ja.com

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

私のコンポーネントのレンダリング機能には、次のものがあります。

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の子としては有効ではありません、screenY、clientX、clientY、ctrlKey、shiftKey、altKey、metaKey、ボタン、ボタン、relatedTarget、pageX、pageY、isDefaultPrevented、isPropagationStopped、_dispatchListeners、_dispatchIDs})。子のコレクションをレンダリングするつもりなら、代わりに配列を使うか、ReactアドオンのcreateFragment(object)を使ってオブジェクトをラップしてください。 Welcomeのrenderメソッドを確認してください。

Map関数内でthis.onItemClick.bind(this, item)から(e) => onItemClick(e, item)に変更した場合、すべて正常に機能します。

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

アップデート1:
onItemClick関数は以下の通りです。this.setStateを削除するとエラーが消えます。

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

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

242
almeynman

私はこのエラーを抱えていました、そして、私が意図せずに私が文字列値であると予想していた私のJSXコードにObjectを含めていたということが判明しました:

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

breadcrumbElementは以前は文字列でしたが、リファクタリングのためにObjectになっていました。残念なことに、Reactのエラーメッセージは問題が存在していた行を私に指摘するのに良い仕事をしませんでした。私は "props"がコンポーネントに渡されていることを認識するまでスタックトレースをさかのぼって追跡しなければなりませんでした。それから問題のあるコードを見つけました。

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

314
Code Commander

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

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

私はちょうど同じエラーが出ましたが、違う間違いが原因です。

{{count}}

正しい値の代わりにcountの値を挿入します。

{count}

これはおそらくコンパイラが{{count: count}}に変わった、すなわちObjectをReactの子として挿入しようとしています。

27
Dogbert

私が今日同じ問題を抱えていたので、これに追加しようと思ったのですが、それが機能し始めた<div>タグでラップしたときに、その関数だけが戻ってきたからです。

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

上記によりエラーが発生しました。 return()セクションを次のように変更して問題を解決しました。

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

...または単に:

return gallerySection
23
user2997982

私は、render()関数のreturn文の中でHTML要素を保持している変数を不必要に中括弧で囲む必要がありました。これにより、Reactはそれを要素ではなくオブジェクトとして扱うようになりました。

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

  return (
    {element}
  )
}

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

12
Liran H

私の小道具の周りの中括弧がプレゼンテーションコンポーネントに送られているのを忘れることと関係がありました。

前:

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

後に

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

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

そして上記のApoorv Bankeyによって投稿されたように。

Firebase V5.0.3以上、Android用のものは、atmがバストです。修正:

npm i --save [email protected]

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

7
RedEarth

反応する子はオブジェクトではなくプリミティブ型であるべきです。検証が確実に行われるように、開発中に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 is passed which is error--->>>{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の一部がプリミティブを参照していないために発生します。 vs this.props.name)。

ソース - https://www.codingbismuth.com/objects-are-not-valid-as-react-child/

7
Meet Zaveri

何らかの理由でFirebaseをインポートした場合。それからnpm i --save [email protected]を実行してみてください。これはfirebaseが反応ネイティブを壊してしまうためです。これを実行すると修正されます。

4
Apoorv Bankey

私も同じ問題を抱えていますが、私の間違いはとてもばかげています。オブジェクトに直接アクセスしようとしていました。

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
Nimmi Verma

私の場合は、レンダリング機能からHTML要素を返すのを忘れていて、オブジェクトを返していました。私がしたのは、{items}をhtml要素でラップしただけです - 下記のような単純なdiv

<ul>{items}</ul>
2
Shan

こんなことが起きたばかりなのですが….

私が書いた:

{response.isDisplayOptions &&
{element}
}

Div内に配置することで修正されました。

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

オブジェクト全体ではなく、単にオブジェクトのキーを使用していました。

より多くの詳細はここで見つけることができます: 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

私の問題は私が次のエラーに直面したときに簡単でした:

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

それは文字列であることを期待して{object}を使用してコンポーネント内でオブジェクトを直接レンダリングしようとしているときにエラーで指定されたキーでオブジェクトを渡していたということでした

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

react Componentでレンダリングしている間、私は以下のようなものを使いました

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

しかしそれはあったはずです

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

このリストに別の解決策を追加したいです。

仕様:

  • "反応": "^ 16.2.0"、
  • "react-dom": "^ 16.2.0"、
  • "react-redux": "^ 5.0.6"、
  • "react-scripts": "^ 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
bprdev

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

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

1
MohammadMasoumi

ステートレスコンポーネントを使用する場合は、次のような形式に従ってください。

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

これは私のために働くようだった

1
ppak10

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

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

はい、知っています。私もこれで45分を失いました。

1

念のため、プロジェクト内のいずれかのファイルをFirebaseを使用している。それでは最後にそのimport firebaseステートメントを置いてください。

私はこれがおかしく聞こえますがそれを試してみてください!

1
KNDheeraj

私もこの「オブジェクトは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チームは文書化された here のような解決策に取り組んでいます。

ケン

1
Ken A Collins

私の問題は非常に特別なものでした。私の.envファイルで、私のapi urlがある行にコメントを入れました:

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

ApiのURLが間違っていたので、ログイン/サインアップしようとするとInvariant violationエラーが出ます。

0
ehacinom

三項演算子で何かをレンダリングするときにこのエラーが発生しました。私がしたこと:

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

次のように、括弧のないバーでなければなりません:

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

私の間違いはそれをこのように書いていたからです。

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

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

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

0
Deke

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>
    );
}
0
Suresh Mangs

renderItem小道具を必要とするコンポーネントを使用しているときにInvariant Violation: Objects are not valid as a React childが私に起こりました。

renderItem={this.renderItem}

私の間違いは私のrenderItemメソッドをasyncにすることでした。

0
vmarquet

明らかに、他の人がこのスレッドで以前に言及したように、React JSXでprops.childrenObject型にすることはできませんこれは、特定の質問の問題の根本原因ではありません。

エラーテキストを注意深く読むと、 SyntheticEvent の署名に一致するオブジェクトをレンダリングしようとしたときに、Reactがエラーを生成したことがわかります。

Uncaught Error: Invariant Violation: Objects are not valid as a React child (found: object with keys {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, type, eventPhase, bubbles, cancelable, timeStamp, defaultPrevented, isTrusted, view, detail, screenX, screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, button, buttons, relatedTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Welcome.

しかし、なぜSyntheticEventをレンダリングしようとしているのか疑問に思う人がいます。ここがあなたの質問に対する本当の答えです。明らかにSyntheticEventをレンダリングするつもりはありませんが、イベントハンドラーパラメータの順序が間違っています

renderメソッドでは、onItemClickイベントハンドラーをクラスコンポーネントのthisにバインドし、引数としてitemを渡します。

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

Function.prototype.bindのドキュメントによると、thisArgの後に渡されるすべての引数はprependedであり、その後ターゲット関数が呼び出されたときに渡される引数に

arg1、arg2、...

ターゲット関数を呼び出すときにバインドされた関数に提供される引数の前に追加する引数。

その後、イベントハンドラーを見ると、パラメーターeがパラメーターitemの前にリストされていることがわかります。

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

onItemClick(e, item)が呼び出されると、itemの呼び出し中に渡されたbindprecedeトリガーのeventになるため、パラメーターeがマップされバインドされますitem、およびパラメータitemeventに設定されます。

setStateが呼び出されると、langが、トリガーとなるSyntheticEventイベントを表すonClickに設定され、this.state.langの値を他の場所でレンダリングしようとすると、不変違反エラーが表示されます。

0
Philip Wrage

私の場合、実行時に注入する必要がある動的配列が原因でした。

オブジェクトにnullチェックを追加したところ、正常に機能しました。

前:

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

後:

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

有効なJSX要素を作成するだけです。私の場合、コンポーネントをオブジェクトに割り当てました。

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

私のコードのどこかで、そのボタンを動的に割り当てたいと思いました。

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

Props compを介して初期化したJSX compを宣言することでこれを解決します。

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

解決策としてStringify()toString()に言及した人のために、私はそれでうまくいったと言いますが、問題とそれがなぜ起こったのかを理解する必要があります。私のコードでは簡単な問題でした。同じ関数を呼び出す2つのボタンがありましたが、1つのボタンがその関数に引数を正しく渡していませんでした。

0
Tanaka
  1. 何が起こっているのかあなたが実装しようとしているonClick関数はすぐに実行されます。

  2. 私たちのコードはHTMLではないのでそれはjavascriptであるのでそれは関数実行として解釈されます。

  3. onClick関数は、関数実行ではなく引数として関数を受け取ります。

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

これは、List ItemにonClick関数を定義します。これは、コンポーネントがレンダリングされるとすぐにはクリックされないで実行されます。

0
Hassan Raza

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

上記のコードでエラーが発生しました。その後、このように書き換えました。

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

Tryブロック内のnew Error()が削除されたことに注意してください。

このエラーメッセージを回避するためにコードを書くより良い方法は、{オブジェクトはthrow-no-throw-literalがスローされることを期待されていますの代わりにthrow new Error()に文字列を渡すことです。 JSXを返して、キャッチブロックにJSXを返します。

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

配列を直接テキストで表示できます。配列を厳格化または反復してFlatListに表示する必要があります。

例えばthis.props.items = ["A"、 "B"、 "C"]

<Text>{JSON.strignify(this.props.items)}</Text>のように表示する必要があります

または

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

私はただこのエラーの本当にばかげたバージョンを通して自分自身を置いています、私はそれを後世のためにここで共有するかもしれません。

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

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

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

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

もちろん、これは無効です。オブジェクトは反応する子としては無効です。

0
shabs

Found:キーを持つオブジェクト

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

から

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

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

あなたは中括弧({})を外しました。

0
Arul Mani