首页 文章

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

提问于
浏览
192

在我的组件的渲染功能中,我有:

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,cancelable,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的render方法 .

如果我在map函数中更改为 this.onItemClick.bind(this, item)(e) => onItemClick(e, item) ,一切都按预期工作 .

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

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

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

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

22 回答

  • 5

    Invariant Violation: Objects are not valid as a React child 在使用需要 renderItem 道具的组件时发生在我身上,例如:

    renderItem={this.renderItem}
    

    而我的错误是让我的 renderItem 方法 async .

  • 1

    我遇到了这个错误,事实证明我无意中在我的JSX代码中包含了一个我希望是字符串值的Object:

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

    breadcrumbElement 曾经是一个字符串,但由于重构已成为一个对象 . 不幸的是,React 's error message didn'做了一个很好的工作,指出我存在问题的路线 . 我必须一直跟踪我的堆栈跟踪,直到我认识到"props"被传递到组件然后我发现了有问题的代码 .

  • 0

    所以我在尝试显示 createdAt 属性时遇到了这个错误,这是一个Date对象 . 如果你像这样连接 .toString() ,它将进行转换并消除错误 . 只是将其作为可能的答案发布,以防其他人遇到同样的问题:

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

    我只是得到了相同的错误,但由于一个不同的错误:我使用双括号,如:

    {{count}}
    

    插入 count 的值而不是正确的:

    {count}
    

    编译器可能会变成 {{count: count}} ,即尝试将Object作为React子进行插入 .

  • 5

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

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

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

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

    ......或者干脆:

    return gallerySection
    
  • 8

    我不得不在不必要的情况下将花括号放在一个变量中,该变量在render()函数的return语句中包含一个HTML元素 . 这使得React将其视为对象而非元素 .

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

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

  • 7

    我不得不忘记发送到演示组件的道具周围的花括号:

    之前:

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

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

    对于任何使用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

  • 24

    反应子/子应该是原始类型而不是对象 . 在开发中使用Proptypes包以确保验证发生 .

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

    • 错误:将对象传递给子级
    <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>
    
    • 成功:将对象的属性(应该是原始属性,即字符串值或整数值)传递给子级 .
    <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) .

    来源 - https://www.codingbismuth.com/objects-are-not-valid-as-react-child/

  • 0

    如果由于某种原因你导入了firebase . 然后尝试运行 npm i --save firebase@5.0.3 . 这是因为firebase break本身反应,所以运行它会修复它 .

  • 1

    我也有同样的问题,但我的错误是如此愚蠢 . 我试图直接访问对象 .

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

    你只是使用对象的键,而不是整个对象!

    更多细节可以在这里找到: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}
    {this.state.new_data.description}
    {this.state.new_data.dependtables}
    </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>
    
  • 277

    我想在此列表中添加另一个解决方案 .

    眼镜:

    • "react":"^16.2.0",

    • "react-dom":"^16.2.0",

    • "react-redux":"^5.0.6",

    • "react-scripts":"^1.0.17",

    • "redux":"^3.7.2"

    我遇到了同样的错误:

    没有捕获错误:对象无效作为React子对象(找到:具有键的对象) . 如果您要渲染子集合,请使用数组 .

    这是我的代码:

    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值放入分派时,一切都按预期开始工作 .

  • 0

    如果您使用Firebase项目中的任何文件 . 然后在最后放置导入firebase语句!!

    我知道这听起来很疯狂,但试试吧!

  • 78

    如果使用无状态组件,请遵循以下格式:

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

    这似乎对我有用

  • 19

    我只是通过一个非常愚蠢的错误版本,我也可以在这里分享后代 .

    我有一些像这样的JSX:

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

    我需要对此进行评论以调试某些内容 . 我在IDE中使用了键盘快捷键,结果如下:

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

    当然,这是无效的 - 对象作为反应孩子无效!

  • 3

    如果使用Firebase,如果它不能通过放在 import 语句的末尾,那么你可以尝试将其置于生命周期方法之一,也就是说,你可以把它放在 componentWillMount() 中 .

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

    我的错误是因为这样写:

    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

    我的问题非常特别:在我的 .env 文件中,我在有我的api url的行中添加了注释:

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

    当我尝试登录/注册时,我会收到 Invariant violation 错误,因为api url是错误的 .

  • 1

    我有同样的问题,在我的情况下,我更新 redux 状态,并且新数据参数与旧参数不匹配,所以当我想通过此错误访问某些参数时,

    也许这种经历有助于某人

  • 3

    当我遇到以下错误时,我的问题很简单:

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

    只是我正在尝试使用直接在组件中渲染对象时,使用错误中指定的键传递一个对象,期望它是一个字符串

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

    在React Component上渲染时,我使用了类似下面的内容

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

    但应该是

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

    感谢a comment by zerkms,我能够注意到我的愚蠢错误:

    当我应该 onItemClick(item, e) 时,我有 onItemClick(e, item) .

相关问题