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

IT技术 javascript reactjs
2021-01-19 19:39:18

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

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、目标、currentTarget、类型、eventPhase、气泡、可取消、时间戳、defaultPrevented、isTrusted、视图、详细信息、screenX 、screenY、clientX、clientY、ctrlKey、shiftKey、altKey、metaKey、getModifierState、按钮、按钮、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,
    });
}

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

6个回答

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

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

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

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

您需要引用作为字符串值的对象的属性,或者将对象转换为所需的字符串表示形式。如果您确实想查看对象的内容,则一种选择可能是 JSON.stringify。
2021-03-25 19:39:18
那么,如果你确实有一个对象,你会如何将它转化为令人向往的东西?
2021-03-26 19:39:18
遇到同样的错误,这个解释解决了我的问题。1 UP 为此。:)
2021-03-30 19:39:18
对于未来的读者:不,不要转换为字符串。改为这样做: const Lcomponent = this.whateverReturnsObject(); 然后在 render(){ return <Lcomponent /> } 就是这样。
2021-04-03 19:39:18
啊,我遇到了同样的错误消息指向错误行的问题 - 它说错误在 this.setState({items: items}) 中,但实际上它在我尝试使用 { this.state.items}。JSON.stringify 修复了它!
2021-04-08 19:39:18

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

{this.props.task.createdAt.toString()}
更广泛的方法是在组件的选择逻辑中使用三元语句,请参阅我对我在这里一直遇到的类似问题的回答stackoverflow.com/a/59108109/1483143
2021-03-14 19:39:18
我肯定有这个问题。我使用的是 DevExtreme 的 React Grid,它不喜欢我的对象数组中的日期属性。使用 .toString() 将其转换为字符串立即有帮助。
2021-03-24 19:39:18
答对了!我遇到了这个问题,但是因为显示它的表可以正常加载(和重新加载)而被抛出了轨道。objects are not valid当我添加一行时,React 只会抛出不变违规原来我在持久化它之前将 Date() 对象转换为一个字符串,所以只有我的新行才有创建日期的对象。:( 向我任性的榜样学习!
2021-04-02 19:39:18

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

{{count}}

插入值count而不是正确的:

{count}

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

我猜你来自 Angular 世界 :D
2021-03-16 19:39:18
{{}} 是什么意思/
2021-03-28 19:39:18
有这个错误——这就是问题所在。在将我的变量分配给构造函数中的 state 时,我this.state = {navMenuItems: {navMenu}};...这基本上将我的 JSXnavMenu变成了一个通用对象。更改为this.state = {navMenuItems: navMenu};摆脱了无意的“强制转换”Object并解决了问题。
2021-04-05 19:39:18
@MuneemHabib 这只是 ES6 语法。React 需要一对{}. 内部对被视为 ES6 代码。在 ES6 中,{count}{count: count}. 因此,当您键入时{{count}},这与{ {count: count} }.
2021-04-07 19:39:18
围绕前端技术弹跳,这是我的问题。现在太明显了!谢谢
2021-04-10 19:39:18

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

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

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

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

...或者简单地说:

return gallerySection
或者你可以简单地使用,return gallerySection如果你想避免额外的div
2021-03-26 19:39:18
回来gallerySection而不是<div>{gallerySection}</div>帮助我。
2021-04-08 19:39:18

React child(singular)应该是原始数据类型而不是对象,或者它可以是 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与 this.props.name)。

来源 - codingbismuth.com

这对我有帮助。返回一个属性而不是一个对象:return <p>{item.whatever}</p>;
2021-03-14 19:39:18
很高兴,您发现它很有用,并感谢您标记链接问题。
2021-03-15 19:39:18
此链接不再有效,但是我发现您的答案的结构在我的用例中是最有用的。此错误在 web 和 react 本机环境中均可产生,并且在尝试使用异步生命周期在组件内 .map() 对象数组时经常作为生命周期错误发生。我在使用 react native react-native-scrollview 时遇到了这个线程
2021-04-05 19:39:18