深度更新React状态(数组)没有Immutable,有什么缺点吗?

时间:2016-08-17 23:05:32

标签: reactjs immutable.js

我知道使用Immutable是一种深度更新React状态的好方法,但我想知道这种方法是否有任何缺点:

假设this.state.members的形状Array<MemberType> MemberType{ userId: String, role: String }

如果用户更改了用户的角​​色,则执行以下方法:

  changeMemberRole = (userId, event, key, value) => {
    const memberIndex = _findIndex(this.state.members,
      (member) => member.userId === userId);

    if (memberIndex >= 0) {
      const newMembers = [...this.state.members];

      newMembers[memberIndex].role = value;
      this.setState({ members: newMembers });
    }
  };

使用Immutable的setIn替换它有什么好处,除了可能更简洁的语法之外?

3 个答案:

答案 0 :(得分:3)

使用与否Immutable.js之间的区别当然是不变性¹:)

当您声明const newMembers = [...this.state.members]您正在复制引用数组时,这确实是一个新数组(通过索引修改直接子项,如01,{{1}没有反映)但是填充了相同的对象引用,因此共享内部/深层更改。这称为浅拷贝

2不是 new

因此,对任何newMembers元素的任何更改也会在相应的newMembers元素中进行。这对你的例子来说很好,到目前为止还没有真正的优势。

那么,为什么不变性?

在小片段中不容易观察到它的真正好处,因为它更多地是关于心态。取自Immutable.js homepage

  

许多使应用程序开发变得困难的因素是跟踪   突变和维持状态。使用不可变数据进行开发   鼓励您以不同的方式思考数据如何流经您的   应用

不变性带来了许多功能范例的好处,例如避免副作用或竞争条件,因为您将变量视为值而不是对象,从而更容易理解其范围和生命周期,从而minimizing bugs

当发生变异时,反应的一个特定优势是safely check for state changes in shouldComponentUpdate

this.state.members

使用对象而不是值// assume this.props.value is { foo: 'bar' } // assume nextProps.value is { foo: 'bar' }, // but this reference is different to this.props.value this.props.value !== nextProps.value; // true nextProps时,将被视为不同的引用(除非我们执行深度比较)并触发重新渲染,这在规模上可能非常昂贵。< / p>

¹除非你模仿自己的不变性,否则我相信this.props.value更好

答案 1 :(得分:0)

你没有复制角色,因此如果你的一个组件扮演道具(如果有的话)不能利用纯渲染优化(覆盖shouldComponentUpdate并检测道具实际改变的时候)。

但是既然你可以在没有immutablejs的情况下制作角色的副本,除了你必须输入更多(因此有更多机会犯错误)之外没有任何有效的区别。这本身就是一个降低生产力的巨大缺点。

答案 2 :(得分:-1)

来自setIn文档:

  

返回在此keyPath处具有设定值的新Map。如果keyPath中的任何键不存在,将在该键上创建一个新的不可变映射。

这可能不是您正在寻找的内容,因为您可能不希望插入具有给定角色的新成员(如果它尚不存在)。这取决于您是否能够控制函数中传递的userId参数并验证它是否存在。

这个解决方案很好。如果您愿意,可以将其替换为update