Javascript 不变违规:对象作为 React 子对象无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33117449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:39:32  来源:igfitidea点击:

Invariant Violation: Objects are not valid as a React child

javascriptreactjs

提问by almeynman

In my component's render function I have:

在我的组件的渲染函数中,我有:

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

everything renders fine, however when clicking the <li>element I receive the following error:

一切都很好,但是当单击该<li>元素时,我收到以下错误:

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.

未捕获错误:不变违规:对象作为 React 子对象无效(发现:对象具有键 {dispatchConfig、dispatchMarker、nativeEvent、目标、currentTarget、类型、eventPhase、气泡、可取消、时间戳、defaultPrevented、isTrusted、视图、详细信息、screenX 、screenY、clientX、clientY、ctrlKey、shiftKey、altKey、metaKey、getModifierState、按钮、按钮、relatedTarget、pageX、pageY、isDefaultPrevented、isPropagationStopped、_dispatchListeners、_dispatchIDs})。如果您打算渲染一组子项,请改用数组或使用 React 附加组件中的 createFragment(object) 包装对象。检查 的渲染方法Welcome

If I change to this.onItemClick.bind(this, item)to (e) => onItemClick(e, item)inside the map function everything works as expected.

如果我改变this.onItemClick.bind(this, item)(e) => onItemClick(e, item)地图功能一切正常的内部预期。

If someone could explain what I am doing wrong and explain why do I get this error, would be great

如果有人能解释我做错了什么并解释为什么我会收到这个错误,那就太好了

UPDATE 1:
onItemClick function is as follows and removing this.setState results in error disappearing.

更新 1:
onItemClick 函数如下,删除 this.setState 会导致错误消失。

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

But I cannot remove this line as I need to update state of this component

但是我无法删除此行,因为我需要更新此组件的状态

回答by Code Commander

I was having this error and it turned out to be that I was unintentionally including an Object in my JSX code that I had expected to be a string value:

我遇到了这个错误,结果是我无意中在我的 JSX 代码中包含了一个我希望是字符串值的对象:

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

breadcrumbElementused to be a string but due to a refactor had become an Object. Unfortunately, React's error message didn't do a good job in pointing me to the line where the problem existed. I had to follow my stack trace all the way back up until I recognized the "props" being passed into a component and then I found the offending code.

breadcrumbElement曾经是一个字符串,但由于重构已经变成了一个对象。不幸的是,React 的错误消息并没有很好地将我指向存在问题的那一行。我不得不一直跟踪我的堆栈跟踪,直到我认识到“道具”被传递到组件中,然后我找到了有问题的代码。

You'll need to either reference a property of the object that is a string value or convert the Object to a string representation that is desirable. One option might be JSON.stringifyif you actually want to see the contents of the Object.

您需要引用作为字符串值的对象的属性,或者将对象转换为所需的字符串表示形式。一种选择可能是JSON.stringify您是否真的想要查看对象的内容。

回答by Brett84c

So I got this error when trying to display the createdAtproperty which is a Date object. If you concatenate .toString()on the end like this, it will do the conversion and eliminate the error. Just posting this as a possible answer in case anyone else ran into the same problem:

因此,当我尝试显示createdAt作为 Date 对象的属性时出现此错误。如果.toString()像这样在最后连接,它将进行转换并消除错误。只需将此作为可能的答案发布,以防其他人遇到同样的问题:

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

回答by Dogbert

I just got the same error but due to a different mistake: I used double braces like:

我刚刚遇到了同样的错误,但由于不同的错误:我使用了双大括号,例如:

{{count}}

to insert the value of countinstead of the correct:

插入值count而不是正确的:

{count}

which the compiler presumably turned into {{count: count}}, i.e. trying to insert an Object as a React child.

编译器大概变成了{{count: count}},即试图插入一个对象作为 React 子对象。

回答by user2997982

Just thought I would add to this as I had the same problem today, turns out that it was because I was returning just the function, when I wrapped it in a <div>tag it started working, as below

只是想我会添加到这个,因为我今天遇到了同样的问题,结果是因为我只返回函数,当我将它包装在一个<div>标签中时它开始工作,如下所示

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

The above caused the error. I fixed the problem by changing the return()section to:

以上导致了错误。我通过将return()部分更改为:

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

...or simply:

...或者简单地说:

return gallerySection

回答by Liran H

Mine had to do with unnecessarily putting curly braces around a variable holding a HTML element inside the return statement of the render() function. This made React treat it as an object rather than an element.

我的问题是在 render() 函数的 return 语句中不必要地将花括号放在一个包含 HTML 元素的变量周围。这使得 React 将其视为对象而不是元素。

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

  return (
    {element}
  )
}

Once I removed the curly braces from the element, the error was gone, and the element was rendered correctly.

一旦我从元素中删除了花括号,错误就消失了,并且元素被正确呈现。

回答by Meet Zaveri

React child(singular) should be type of primitivedata typenot object or it could be JSX tag(which is not in our case). Use Proptypes package in development to make sure validation happens.

React child(singular)应该是原始数据类型而不是对象,或者它可以是 JSX 标签(在我们的例子中不是)。在开发中使用 Proptypes 包以确保进行验证。

Just a quick code snippet(JSX) comparision to represent you with idea :

只是一个快速的代码片段(JSX)比较来代表你的想法:

  1. Error : With object being passed into child

    <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. Without error : With object's property(which should be primitive, i.e. a string value or integer value) being passed into 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>
    
  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; (From the source below) : Make sure all of the items you're rendering in JSX are primitives and not objects when using React. This error usually happens because a function involved in dispatching an event has been given an unexpected object type (i.e passing an object when you should be passing a string) or part of the JSX in your component is not referencing a primitive (i.e. this.props vs this.props.name).

TLDR;(来自下面的来源):使用 React 时,请确保您在 JSX 中呈现的所有项目都是基元而不是对象。发生此错误通常是因为参与调度事件的函数被赋予了意外的对象类型(即在您应该传递字符串时传递对象)或组件中的部分 JSX 未引用原语(即 this.props与 this.props.name)。

Source - codingbismuth.com

来源 - codingbismuth.com

回答by steveareeno

Mine had to do with forgetting the curly braces around props being sent to a presentational component:

我的与忘记发送到展示组件的 props 周围的花括号有关:

Before:

前:

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

After

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

回答by Ken A Collins

I too was getting this "Objects are not valid as a React child" error and for me the cause was due to calling an asynchronous function in my JSX. See below.

我也收到了这个“对象作为 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>
        );
    }
}

What I learned is that asynchronous rendering is not supported in React. The React team is working on a solution as documented here.

我学到的是 React 不支持异步渲染。React 团队正在研究此处记录的解决方案。

回答by RedEarth

For anybody using Firebase with Android, this only breaks Android. My iOS emulation ignores it.

对于在 Android 上使用 Firebase 的任何人,这只会破坏 Android。我的 iOS 模拟忽略了它。

And as posted by Apoorv Bankey above.

正如上面 Apoorv Bankey 发布的那样。

Anything above Firebase V5.0.3, for Android, atm is a bust. Fix:

任何高于 Firebase V5.0.3 的东西,对于 Android 来说,atm 都是一团糟。使固定:

npm i --save [email protected]

Confirmed numerous times here https://github.com/firebase/firebase-js-sdk/issues/871

在这里多次确认 https://github.com/firebase/firebase-js-sdk/issues/871

回答by Nimmi Verma

I also have the same problem but my mistake is so stupid. I was trying to access object directly.

我也有同样的问题,但我的错误太愚蠢了。我试图直接访问对象。

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

}