React:为什么道具没有被冻结?

React: Why are props not frozen?

React 建议不要改变 props。我是在这样的印象下操作的,当 props 被传入时,它们将是不可变的或冻结的。

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

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

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

this.props.a = [1,2,3]; 不行

this.props.a.push(123); 可以。

this.props.a = {name: 'John Doe'} 不行

this.props.a.name = 'John Doe' 会起作用

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

Uncaught TypeError: Cannot assign to read only property a ...

这不是真的。默认情况下,道具是可变的。如果你使用的是 ES2015,你可以让它们 read-only 在你的函数中执行以下操作:

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-helper or https://facebook.github.io/immutable-js/

它不会抛出任何错误,除非你明确地冻结 object(props)。

道具是从 parent 接收的,并且就接收它们的组件而言是不可变的。

即默认情况下,React props 是不可变的,因为您的组件关心的是将它们维护为从 parent 接收的数据并按原样使用。我们可以使用 state 来维护可以随时更改的本地(组件级数据)并与 parent.

保持 props 合同

我不确定其背后的确切原因,或者是否在某处记录了这一点,但我可以猜测:

除了使用 new-ish 或什至尚未实现的浏览器功能外,冻结对变量的任何赋值并不容易,甚至不一定可能。此外,深度冻结您应用中的所有道具可能会对性能产生影响,并且肯定需要为产品构建移除。

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

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

which you cannot possibly obtain in legacy engines

如果有人改变了某些东西怎么办? 这些道具是浅拷贝的,这意味着除非你修改,否则你不会影响父道具嵌套对象。但是,即使您这样做也不会影响应用程序,因为它会在下一次渲染时被清除(就像您的修改一样)。

如果我有什么不对的地方请告诉我!这只是我的推理。