React:为什么props没有被冻结?

IT技术 reactjs immutability
2021-05-22 01:54:41

React 建议不要改变 props。我当时的印象是,当 props 传入时,它们将是不可变的或冻结的。

下面的代码不会抛出任何错误并改变props。这是一个错误吗?

try{
  var a = this.props.a;
  a.push('one')
  a.push('two')
  a.push('three')
  console.log(a)
}catch(err){
  console.log(err)
}
4个回答

我不确定其背后的确切原因,或者是否有记录在案,但我可以猜测:

除了使用 new-ish 甚至尚未实现的浏览器功能之外,冻结对变量的任何分配并不容易,甚至不一定可能。此外,深度冻结应用程序中的所有 props 可能会对性能产生影响,并且肯定需要在 prod 构建中删除。

你能冻结原始变量的赋值吗?我不这么认为。我认为 babelconst通过在编译时静态检查代码来做到这一点

你能在没有 Object.freeze 或 ES7 代理的情况下冻结对象吗?我再次不这么认为, es5-shim自述文件说:

您不可能在传统引擎中获得

如果有人确实使某些东西发生了变异怎么办?这些props是浅复制的,这意味着除非您修改嵌套对象,否则您不会影响父props。但是,即使您这样做了,它也不会影响应用程序,因为它会在下一次渲染中消失(就像您的修改一样)。

如果我做错了什么,请告诉我!这只是我的推理。

除非您明确冻结对象(props),否则它不会引发任何错误。

就接收它们的组件而言,props是从父母那里收到的,并且是不可变的。

即默认情况下 Reactprops是不可变的,因为您的组件需要将它们维护为从父级接收的数据并按原样使用。我们可以state用来维护可以随时更改的本地(组件级数据)并与父级保持 props 合同。

似乎这与之前的行为相同const,您无法重新分配值,但您仍然可以推送到数组或向对象添加键,因为它们不受保护。无论如何,尽管有可能进行这些突变,但您不应该这样做。

this.props.a = [1,2,3]; 不会工作

this.props.a.push(123); 将工作。

this.props.a = {name: 'John Doe'} 不会工作

this.props.a.name = 'John Doe' 将工作

如果您尝试重新分配组件中的 prop,则会发生类型错误。

未捕获的类型错误:无法分配给只读属性 a ...

这不是真的。默认情况下,props是可变的。如果您使用的是 ES2015,您可以在您的函数中将它们设为只读,执行以下操作:

const { a } = this.props; // would create a const variable 'a'.

与...一样:

const a = this.props.a;

虽然您现在无法重新分配'a',但您仍然可以对其进行变异。意思是,a = 'foo';会抛出一个错误,但你仍然可以做到a.push('foo');

如果您想使用不可变的数据结构,请尝试使用https://github.com/kolodny/immutability-helperhttps://facebook.github.io/immutable-js/