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

alm*_*man 296 javascript reactjs

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

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>
    );
  }
Run Code Online (Sandbox Code Playgroud)

一切都很好,但是当点击<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.

如果我改变this.onItemClick.bind(this, item)(e) => onItemClick(e, item)里面的地图功能一切正常.

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

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

onItemClick(e, item) {
    this.setState({
      lang: item,
    });
}
Run Code Online (Sandbox Code Playgroud)

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

Cod*_*der 367

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

return (
    <BreadcrumbItem href={routeString}>
        {breadcrumbElement}
    </BreadcrumbItem>
)
Run Code Online (Sandbox Code Playgroud)

breadcrumbElement曾经是一个字符串,但由于重构已成为一个对象.不幸的是,React的错误信息并没有很好地指出我存在问题的那一行.我必须一直跟踪我的堆栈跟踪,直到我认识到传递给组件的"props",然后我找到了有问题的代码.

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

  • 那么,如果你确实有一个物体,你会如何将它转化为可取的东西呢? (11认同)
  • 您需要引用作为字符串值的对象的属性,或者将Object转换为所需的字符串表示形式.如果您确实想要查看Object的内容,则一个选项可能是JSON.stringify. (4认同)
  • 遇到同样的错误,这个解释解决了我的问题。1 UP 为此。:) (3认同)

Bre*_*84c 92

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

{this.props.task.createdAt.toString()}
Run Code Online (Sandbox Code Playgroud)

  • 答对了!我遇到了这个问题,但是因为正在显示它的表会加载(并重新加载)就好了.当我**添加**行时,React只会抛出`对象无效`不变违规.事实证明我在保持它之前将Date()对象转换为字符串,因此只有我的新行具有创建日期的对象.:(从我的任性示例人学习! (2认同)

Dog*_*ert 31

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

{{count}}
Run Code Online (Sandbox Code Playgroud)

插入值count而不是正确的:

{count}
Run Code Online (Sandbox Code Playgroud)

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

  • {{}}的意思是/ (3认同)
  • @MuneemHabib它只是ES6语法.React需要一对`{}`.内部对被视为ES6代码.在ES6中,`{count}`与`{count:count}`相同.因此,当您键入`{{count}}`时,这与`{{count:count}}`完全相同. (3认同)
  • 有这个错误——这就是问题所在。在将我的变量分配给构造函数中的 state 时,我有 `this.state = {navMenuItems: {navMenu}};` ... 这基本上将我的 JSX `navMenu` 变成了一个通用对象。更改为 `this.state = {navMenuItems: navMenu};` 摆脱了无意的“强制转换”到 `Object` 并修复了问题。 (2认同)

use*_*982 27

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

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

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

return (
  <div>
    {gallerySection}
  </div>
);
Run Code Online (Sandbox Code Playgroud)

......或者干脆:

return gallerySection
Run Code Online (Sandbox Code Playgroud)

  • 或者如果你想避免额外的`div`,你可以简单地使用`return gallerySection` (7认同)
  • 返回`gallerySection`而不是`<div> {gallerySection} </ div>`帮助了我. (4认同)

Lir*_*n H 15

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

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

  return (
    {element}
  )
}
Run Code Online (Sandbox Code Playgroud)

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


ste*_*eno 10

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

之前:

const TypeAheadInput = (name, options, onChange, value, error) => {
Run Code Online (Sandbox Code Playgroud)

const TypeAheadInput = ({name, options, onChange, value, error}) => {
Run Code Online (Sandbox Code Playgroud)


Mee*_*eri 9

反应子/子应该是原始类型而不是对象.在开发中使用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>
    
    Run Code Online (Sandbox Code Playgroud)
  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>
    
    Run Code Online (Sandbox Code Playgroud)

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

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

  • 该链接不再起作用,但是我发现您的答案的结构在我的用例中是最有用的。此错误在Web环境和本机环境中均会产生,并且在尝试使用异步生命周期尝试对组件内的对象数组进行.map()时,通常会作为生命周期错误发生。我在使用react native react-native-scrollview时遇到了这个线程 (2认同)
  • 这对我有帮助。返回属性而不是对象:`return &lt;p&gt;{item.whatever}&lt;/p&gt;;` (2认同)

小智 7

对于任何使用Android版Firebase的人来说,这只能打破Android.我的iOS模拟忽略了它.

并由Apoorv Bankey发布.

Firebase V5.0.3以上的任何东西,对于Android,atm都是一个破产.固定:

npm i --save firebase@5.0.3
Run Code Online (Sandbox Code Playgroud)

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


cor*_*ons 7

通常会出现这种情况,因为您没有正确解构。以这段代码为例:

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

const SomeForm = () => (
  <Button text="Save" />
)
Run Code Online (Sandbox Code Playgroud)

我们用= text =>参数声明它。但实际上,React 希望这是一个包罗万象的props对象。

所以我们真的应该做这样的事情:

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

const SomeForm = () => (
  <Button text="Save" />
)
Run Code Online (Sandbox Code Playgroud)

注意到区别了吗?props这里的param 可以命名为任何东西(props只是与命名法匹配的约定),React 只是期待一个带有键和值的对象。

通过对象解构,您可以并且经常会看到这样的事情:

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

const SomeForm = () => (
  <Button text="Save" />
)
Run Code Online (Sandbox Code Playgroud)

...哪个有效。

有可能,任何偶然发现这个的人只是在没有解构的情况下意外地声明了他们组件的 props 参数。


Nim*_*rma 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>
        );
    }                                                                             

}
Run Code Online (Sandbox Code Playgroud)


Ken*_*ins 6

我也收到了“对象作为React child无效”错误,对我来说,原因是由于在我的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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Nam*_*yev 6

只需删除 return 语句中的花括号。

前:

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

后:

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


小智 6

这是我的代码:

class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      value: null,
      getDatacall : null
    }
    this.getData = this.getData.bind(this)
  }
  getData() {
  //   if (this.state.getDatacall === false) {
    sleep(4000)
    returnData("what is the time").then(value => this.setState({value, getDatacall:true}))
    // }
  }
  componentDidMount() {
    sleep(4000)

    this.getData()
  }
  render() {
    this.getData()
    sleep(4000)
    console.log(this.state.value)
    return (
      <p> { this.state.value } </p>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

当我遇到有问题的错误时。我不得不将其更改为:

 render() {
    this.getData()
    sleep(4000)
    console.log(this.state.value)
    return (
      <p> { JSON.stringify(this.state.value) } </p>
    )
  }
Run Code Online (Sandbox Code Playgroud)


小智 5

就我而言,我忘记从渲染函数返回一个 html 元素,而我正在返回一个对象。我所做的是我只是用一个 html 元素包裹了 {items} - 一个简单的 div,如下所示


小智 5

我遇到了同样的问题,因为我没有将 放在props花括号中。

export default function Hero(children, hero ) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您的代码与上述代码类似,那么您将收到此错误。要解决这个问题,只需在props.

export default function Hero({ children, hero }) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我得到了同样的错误,我改变了这个

export default withAlert(Alerts)

对此

export default withAlert()(Alerts).

在旧版本中,以前的代码没问题,但在更高版本中它会引发错误。所以使用后面的代码来避免错误。


alm*_*man -3

感谢zerkms 的评论,我能够注意到我的愚蠢错误:

onItemClick(e, item)当我应该拥有的时候我却拥有了onItemClick(item, e)