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

时间:2017-01-13 18:33:04

标签: reactjs immutability

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

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

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

4 个答案:

答案 0 :(得分:1)

我不确定背后的确切推理,或者是否在某处记录了但我可以猜测:

冻结对变量的任何赋值并不容易,甚至不可能在使用new-ish之外,甚至是未实现的浏览器功能之外。同样深度冻结你的应用程序中的所有道具可能会产生性能影响,并且肯定需要删除prod构建。

你能冻结原始变量的分配吗? 我不这么认为。我认为babel通过在编译时静态检查代码来使用const来完成它。

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

  

你无法在传统引擎中获得

如果有人改变某些内容怎么办? 这些道具是浅层复制的,这意味着除非修改嵌套对象,否则不会影响父道具。但是,即使你这样做也不会影响应用程序,因为在下一个渲染中会被删除(就像你的修改一样)。

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

答案 1 :(得分:0)

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

this.props.a = [1,2,3];无法工作

this.props.a.push(123);将有效。

this.props.a = {name: 'John Doe'}无法工作

this.props.a.name = 'John Doe'将有效

如果您尝试重新分配组件中的道具,则会出现类型错误。

  

未捕获的TypeError:无法分配给只读属性a ...

答案 2 :(得分:0)

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

收到来自父母的道具,并且就接收它们的组件而言是不可变的。

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

答案 3 :(得分:-1)

事实并非如此。道具默认是可变的。如果您正在使用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/