【问题标题】:React: Why are props not frozen?React:为什么 props 没有被冻结?
【发布时间】:2017-01-13 18:33:03
【问题描述】:

React 建议不要改变 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)
}

【问题讨论】:

    标签: reactjs immutability


    【解决方案1】:

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

    在使用新的或什至尚未实现的浏览器功能之外,冻结对变量的任何分配都不容易,甚至不一定可能。此外,深度冻结应用中的所有道具可能会对性能产生影响,并且肯定需要在产品构建中删除。

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

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

    你不可能在旧引擎中获得

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

    如果我有什么问题,请告诉我!这只是我的推理。

    【讨论】:

    • 感谢您的精彩解释。您可能想要研究的一种解释是关于变异某些东西。我能够成功地改变一个通过 redux 作为道具传入的数组(推送项目)。我的更改被持久化到 redux 存储中,因此出现了这个问题。
    • 哦,这很有趣——你肯定不会通过一个行动把他们送回去吗?我需要检查反应源,我记得看到上下文的浅拷贝,并假设他们也会为道具做这件事
    • 是的,我绝对没有通过任何操作对其进行更新,并且惊讶地发现商店正在更新并保留我的更改。也许数组被特殊对待。我没有尝试使用常规对象。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      似乎这与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 ...

      【讨论】:

        【解决方案4】:

        这不是真的。默认情况下,道具是可变的。如果您使用的是 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/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-13
          • 2021-07-31
          • 2020-10-24
          • 2012-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多