反应:无法添加属性'X',对象不可扩展

Posted

技术标签:

【中文标题】反应:无法添加属性\'X\',对象不可扩展【英文标题】:React : cannot add property 'X', object is not extensible反应:无法添加属性'X',对象不可扩展 【发布时间】:2019-08-29 05:54:36 【问题描述】:

我在我的组件中接收道具。我想用这个组件中的道具添加一个属性“LegendPosition”。我无法做到这一点。请帮我解决一下这个。 我已经尝试过这段代码但没有成功:

var tempProps     = this.props;
tempProps.legendPosition = 'right';
Object.preventExtensions(tempProps);

console.log(tempProps);

【问题讨论】:

看这里***.com/a/24943743/4650675 【参考方案1】:

您不能修改this.props。这里tempPropsthis.props 的引用,所以它不起作用。您应该使用JSON.parse()JSON.stringify() 创建props 的副本

var tempProps = JSON.parse(JSON.stringify(this.props));
tempProps.legendPosition = 'right';
Object.preventExtensions(tempProps);

console.log(tempProps);

如需更好更有效的深度克隆对象方法,请参阅What is the most efficient way to deep clone an object in javascript?

【讨论】:

因此,您不是将其作为重复项关闭,而是将所述重复项中的一个答案添加为您自己的... @Andreas 问题不在于如何复制对象。问题是为什么没有克隆的道具不会发生变异。如果他访问了这个问题,他就会解决这个问题 @MaheerAli 您的代码正在运行,但我的子组件没有获得更新的道具。我不知道为什么。请检查您编辑的答案 @AnkitKaushal 你不能改变props。 props 只能由组件的父级更新。您可以更改tempProps 并在渲染方法中使用tempProps 或在任何您想显示props 好的。 @MaheerAli。我会尝试使用 tempProps 。感谢您的帮助【参考方案2】:

props 是不可变的,你不能向它们“添加”任何东西。如果你想“复制”它们,那么你需要这样做

const tempProps = ...this.props;

我可以看到您需要添加更多道具的唯一原因是将其传递给孩子,但您可以在不将其添加到道具对象的情况下做到这一点。

编辑:添加带有额外道具的道具

<Component ...this.props legendPosition="right" />

【讨论】:

注意:这是一个浅拷贝,我不建议不要做深拷贝,因为它搞砸了任何类型的优化反应都会尝试。 提供了一种更好的复制对象的方法。 @Joey 是的,我想将更新后的道具发送到子组件,如果可以不复制或克隆到新对象,请帮助我如何实现。【参考方案3】:

tempProps 对象spread 运算符下面复制您的this.props 对象,在spread 运算符之后,我们可以添加新的对象属性或者我们可以更新现有的对象属性。

var tempProps = 
  ...this.props,
  tempProps.legendPosition = 'right' //property you want to add in props object
;

【讨论】:

【参考方案4】:

我想将更新的道具发送到子组件,如果可以不复制或克隆到新对象,请帮助我如何实现这一点。

解决方法很简单:

<ChildComponent ...this.props legendPosition="right" />

当然legendPosition 将在ChildComponent 中由this.props.legendPosition 提供。

当然更早的this.props 可以包含legendPosition 属性/值,这些属性/值将被稍后定义的内容覆盖 - 顺序很重要

当然可以有许多扩展运算符 - 用于多个属性、逻辑块……随便:

const additonalProps = 
  legendPosition: 'right',
  sthElse: true

return (
  <ChildComponent ...this.props ...additonalProps />
)

【讨论】:

【参考方案5】:

你的答案在这一行。

var tempProps = this.props;

this.props 是不可变的,这意味着您不能更改函数中的属性值。 你可以使用 this.state 以便在你的函数中修改它

    props --- 你不能改变它的值。 states --- 你可以在你的代码中改变它的值,但是它会在渲染时激活 发生。

【讨论】:

以上是关于反应:无法添加属性'X',对象不可扩展的主要内容,如果未能解决你的问题,请参考以下文章

类型错误:无法添加属性 1,对象不可扩展↵ 在 Array.push (<anonymous>)

反应式扩展、锁和线程

代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性“电子邮件”:对象不可扩展”

Object.preventExtensions()使用技巧

ES6新语法之---对象字面量扩展模板字符串

升级到 Apollo 客户端 2 后尝试向结果 gql 数据对象添加字段时出现“对象不可扩展”