ChatGPT解决这个技术问题 Extra ChatGPT

Invariant Violation:对象作为 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 子项无效(发现:带有键的对象 {dispatchConfig、dispatchMarker、nativeEvent、target、currentTarget、type、eventPhase、bubbles、cancelable、timeStamp、defaultPrevented、isTrusted、view、detail、screenX 、screenY、clientX、clientY、ctrlKey、shiftKey、altKey、metaKey、getModifierState、按钮、按钮、relatedTarget、pageX、pageY、isDefaultPrevented、isPropagationStopped、_dispatchListeners、_dispatchIDs})。如果您打算渲染一组子对象,请改用数组或使用 React 附加组件中的 createFragment(object) 包装对象。检查 Welcome 的渲染方法。

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

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

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

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

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

那么this.onItemClick是如何实现的呢?
@zerkms 感谢您的回复,我更新了问题,是的,问题似乎出在 this.setState() 中,但为什么会抛出此错误? :(
如果您将 async 放在函数组件上,也会发生这种情况
一个好的做法是不要在渲染方法中使用 bind。当您在渲染函数中使用 bind 时,会在调用渲染方法时创建一个新的 onItemClick 实例。因此,您可以使用箭头函数语法或在构造函数中绑定您的方法。您可以在官方指南 reactjs.org/docs/handling-events.html 中找到更多详细信息。
谢谢@PetrosKyriakou。我错误地使我的 render() 方法异步。你摇滚!

A
AndrewL64

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

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

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

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


那么,如果你确实有一个对象,你会如何把它变成你想要的东西呢?
您需要引用作为字符串值的对象的属性,或者将对象转换为所需的字符串表示形式。如果您真的想查看对象的内容,一个选项可能是 JSON.stringify。
遇到同样的错误,这个解释解决了我的问题。 1 UP 为此。 :)
啊,我遇到了指向错误行的错误消息的相同问题 - 它说错误出现在 this.setState({items: items}) 中,而实际上它在我试图使用 { 显示该变量的位置进一步爆炸时这个.state.items}。 JSON.stringify 修复了它!
对于未来的读者:不,不要转换为字符串。改为这样做: const Lcomponent = this.whateverReturnsObject();然后在 render(){ return } 就是这样。
D
Devid Farinelli

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

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

答对了!我遇到了这个问题,但是因为显示它的表会加载(和重新加载)就好了,所以我偏离了轨道。当我添加一行时,React 只会抛出 objects are not valid 不变违规。原来我在持久化之前将 Date() 对象转换为字符串,因此只有我的新行具有创建日期的对象。 :( 向我任性的榜样学习!
一种更广泛的方法是在组件的选择逻辑中使用三元语句,请参阅我对我在这里一直遇到的类似问题的回答stackoverflow.com/a/59108109/1483143
我肯定有这个问题。我使用的是 DevExtreme 的 React Grid,它不喜欢我的对象数组中的 date 属性。使用 .toString() 将其转换为字符串会立即有所帮助。
D
Dogbert

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

{{count}}

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

{count}

编译器大概变成了 {{count: count}},即尝试将 Object 作为 React 子插入。


{{}} 的用途/
@MuneemHabib 这只是 ES6 语法。 React 需要一对 {}。内部对被视为 ES6 代码。在 ES6 中,{count}{count: count} 相同。因此,当您键入 {{count}} 时,它与 { {count: count} } 完全相同。
有这个错误——这就是问题所在。在将我的变量分配给构造函数中的状态时,我有 this.state = {navMenuItems: {navMenu}}; ...这基本上将我的 JSX navMenu 变成了一个通用对象。更改为 this.state = {navMenuItems: navMenu}; 消除了对 Object 的无意“强制转换”并解决了该问题。
我猜你来自 Angular 世界:D
围绕前端技术弹跳,这是我的问题。现在太明显了!谢谢
R
Ronan Boiteau

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

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

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

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

...或者简单地说:

return gallerySection

或者,如果您想避免额外的 div,您可以简单地使用 return gallerySection
返回 gallerySection 而不是 <div>{gallerySection}</div> 对我有帮助。
M
Meet Zaveri

React child(singular) 应该是 primitive 数据类型而不是 object 或 它可能是 JSX 标签(在我们的例子中不是)。在开发中使用 Proptypes 包来确保进行验证。

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

错误:将对象传递给子

{/* 项目是带有用户名及其其他详细信息的对象 */} {items.map((item, index) => { return
--item object invalid as react child--->>>{item}
; })}
没有错误:带有对象的属性(应该是原始的,即字符串值或整数值)被传给孩子。
{/* item 是带有用户名及其其他详细信息的对象 */} {items.map((item, index) => { return
--注意 name 属性是原始--->{item.name}
; })}

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

资料来源-codingbismuth.com


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

我的问题与忘记发送到演示组件的道具周围的花括号有关:

前:

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

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

我的问题与您的问题最相似,因此应用您的解决方案对我有所帮助。 +1,谢谢!
L
Let Me Tink About It

我也收到了这个“对象作为 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 团队正在研究解决方案 as documented here


你应该做的是在数据进入时更新状态,然后使用状态值渲染组件
你应该做的是在数据进入时更新状态,然后使用状态值渲染组件
这对我有帮助
L
Liran H

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

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

  return (
    {element}
  )
}

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


谢谢!从元素中删除花括号也对我有用!
g
geisterfurz007

对于任何使用 Firebase 和 Android 的人来说,这只会破坏 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


对于尝试以下 KNDheeraj 提出的解决方案的任何人,如果您使用 Firebase 项目中的任何文件,请投 1 票反对。然后只需将 import firebase 语句放在最后!我知道这听起来很疯狂,但试试看!! **************** 我确实尝试过,这不是 iOS 的解决方案,但仅适用于 Windows 上的 Android。
N
Nimmi Verma

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

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

}

哇,这有帮助我不明白你为什么必须访问对象个人
c
corysimmons

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

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

const SomeForm = () => (
  <Button text="Save" />
)

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

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

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

const SomeForm = () => (
  <Button text="Save" />
)

注意到区别了吗?这里的 props 参数可以命名为任何名称(props 只是与命名法相匹配的约定),React 只是期望一个带有键和 val 的对象。

使用 object destructuring,您可以并且经常会看到这样的事情:

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

const SomeForm = () => (
  <Button text="Save" />
)

...这行得通。

很可能,任何偶然发现它的人只是不小心声明了他们组件的 props 参数而没有解构。


这应该显示为正确答案,新手错误;)
A
Abhirajshri Winsome

只需删除 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
}

后:

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
}

D
Dharman

我遇到了同样的问题,因为我没有将 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>
    );
}

我没有说不是。我认为您的答案在缩进中看起来更好。如果您不同意,请随时回滚。
S
Shubham Patil

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

export default withAlert(Alerts)

对此

export default withAlert()(Alerts)

在旧版本中,以前的代码是可以的,但在以后的版本中它会引发错误。所以使用后面的代码来避免错误。


P
PalPalash

这是我的代码:

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

我遇到了这个错误。我不得不把它改成

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

希望这对某人有帮助!


R
Ronan Boiteau

如果由于某种原因您导入了 firebase。然后尝试运行 npm i --save firebase@5.0.3。这是因为 firebase 破坏了 react-native,所以运行它会修复它。


S
Shan

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

    {项目}


A
Abhirajshri Winsome

只需删除组件中的 async 关键字即可。

const Register = () => {

在此之后没有问题。


t
tolga

就我而言,我向我的子函数组件添加了一个 async 并遇到了这个错误。不要对子组件使用异步。


c
cormacncheese

每当我在 FlatList 中的 renderItem 函数上调用 async 时,都会出现此错误。

在调用 FlatList 中的状态数据之前,我必须创建一个新函数来将我的 Firestore 集合设置为我的状态。


我得到了同样的导航调用的异步函数引起的
t
thelonglqd

我的情况在使用 reduce 时很常见,但这里没有分享,所以我发布了它。

通常,如果您的数组如下所示:

[{ value: 1}, {value: 2}]

并且您想在此数组中呈现 value 的总和。 JSX 代码看起来像这样

<div>{array.reduce((acc, curr) => acc.value + curr.value)}</div>

当您的数组只有一项时会出现问题,例如:[{value: 1}]。 (通常,当您的数组是来自服务器的响应时会发生这种情况,因此您不能保证该数组中的项目数)

reduce 函数在数组只有一个元素时返回元素本身,在这种情况下它是 {value: 1}(一个对象),它会导致 Invariant Violation: Objects are not valid as a React child错误。


C
Cody Gray

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

可在此处找到更多详细信息:https://github.com/gildata/RAIO/issues/48

从'react'导入反应,{组件};从 'prop-types' 导入 PropTypes;类 SCT 扩展组件 { 构造函数(道具,上下文){ 超级(道具,上下文); this.state = { data: this.props.data, new_data: {} }; } componentDidMount() { 让 new_data = this.state.data; console.log(`new_data`, new_data); this.setState( { new_data: Object.assign({}, new_data) } ) } render() { return (

this.state.data = {JSON.stringify(this.state.data)}
{this.state.new_data.name}
{this.state.new_data.description}
{this.state.new_data.dependtables}< br />
); } } SCT.propTypes = { 测试:PropTypes.string,数据:PropTypes.object.isRequired };出口{SCT};导出默认 SCT;


L
Lucas Bustamante

如果您使用 Firebase 并看到此错误,则值得检查您是否正确导入它。从 5.0.4 版开始,您必须像这样导入它:

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

是的,我知道。我也为此浪费了 45 分钟。


谢谢你。它解决了我的 firebase (5.9.2) 问题:)
s
shabs

我只是让自己经历了这个错误的一个非常愚蠢的版本,我不妨在这里分享给后代。

我有一些这样的 JSX:

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

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

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

这当然是无效的——对象作为反应子级无效!


b
bprdev

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

眼镜:

“反应”:“^16.2.0”,

“反应域”:“^16.2.0”,

"react-redux": "^5.0.6",

“反应脚本”:“^1.0.17”,

“还原”:“^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 值放入调度时,一切都开始按预期工作。


K
KNDheeraj

如果您使用 Firebase 项目中的任何文件。然后只需将 import firebase 语句放在最后!

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


P
Phoenix

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

也许这种经历可以帮助某人


就我而言,(Django)ListSerializer 和 CreateSerializer 返回相同的字段,其中一些(取决于您的项目)只是只读字段,因此每次创建新数据时都只需简单地更新 redux 状态
k
kaushalop

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

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

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

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

在 React 组件上渲染时,我使用了类似下面的东西

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

但它应该是

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

p
ppak10

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

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

这似乎对我有用


O
Oranit Dar

这样的事情刚刚发生在我身上...

我写:

{response.isDisplayOptions &&
{element}
}

将其放置在 div 中对其进行了修复:

{response.isDisplayOptions &&
    <div>
        {element}
    </div>
}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅