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
如果有人改变了某些东西怎么办? 这些道具是浅拷贝的,这意味着除非你修改,否则你不会影响父道具嵌套对象。但是,即使您这样做也不会影响应用程序,因为它会在下一次渲染时被清除(就像您的修改一样)。
如果我有什么不对的地方请告诉我!这只是我的推理。
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.
我不确定其背后的确切原因,或者是否在某处记录了这一点,但我可以猜测:
除了使用 new-ish 或什至尚未实现的浏览器功能外,冻结对变量的任何赋值并不容易,甚至不一定可能。此外,深度冻结您应用中的所有道具可能会对性能产生影响,并且肯定需要为产品构建移除。
你能冻结原始变量的赋值吗?我不这么认为。我认为 babel 通过在编译时静态检查代码来使用 const
来做到这一点。
你能在没有 Object.freeze 或 ES7 代理的情况下冻结对象吗? 同样我不这么认为,es5-shim 自述文件说:
which you cannot possibly obtain in legacy engines
如果有人改变了某些东西怎么办? 这些道具是浅拷贝的,这意味着除非你修改,否则你不会影响父道具嵌套对象。但是,即使您这样做也不会影响应用程序,因为它会在下一次渲染时被清除(就像您的修改一样)。
如果我有什么不对的地方请告诉我!这只是我的推理。