不可变的vs javascript数组,对象 - 什么是正确的平衡?

时间:2016-06-02 10:12:29

标签: javascript reactjs redux immutable.js

我建立了我的堆栈(其中包括)react,redux,immutable。我的redux商店使用不可变的地图,列表构建。但是,在反应组件级别,它更容易操作普通的js数组和对象。

那么平衡是什么?来自状态的不可变对象是否应该转换为所有组件的常规js,并且传递回reducer的数据转换回不可变更新状态?

我目前正在逐个组件的基础上进行此操作,但有兴趣了解任何当前(事实上的)最佳实践。

2 个答案:

答案 0 :(得分:1)

在我看来,拥抱永恒并坚持下去。即使在组件级别操作js数据类型似乎更容易,但是不可变的优势使您在良好的实践和性能方面具有优势。

如果您在商店中使用不可变,请在组件中使用它。

答案 1 :(得分:1)

TL; DR

  • 商店是Immutable.Map
  • 商店通过gettersselectors将数据转置为普通js对象公开数据:const getFooItem(state, itemId) => state.getIn(['item',itemId]).toJS()
  • Dumbs组件通过props
  • 将数据作为普通js对象使用

Immutable.js用于您的redux商店

我认为你绝对应该使用Immutable.js为redux商店,因为它确保你保留一个不可变的商店。即使使用新的ES6语法,它也不像纯javascript那样容易出错。例如,假设您的州的一部分看起来像这样:

state = {
   items: {
       'id1': {...your_fo_object_with_id1...},
       'id2': {...your_fo_object_with_id2...},
       etc.
   }
}

现在您要使用id2填充项目,这样您就可以写下这样的内容:

return {
    ...state,
    items: {
        ...items, //Do not forget this line, if you do, no error will be thrown, but your state will be in a bad state since all others items will be lost 
        [action.id]: action.item
    }
}

您是否注意到我的评论?如果有可能做出这样的遗漏(即忘记复制以前的状态),产生如此大的影响,你可以确定你迟早会成功。问问我怎么知道......

使用Immutable.js语法本身可以避免这种错误:

return state.updateIn(['items', 'id1'], () => Immutable.fromJS(action.item)))

使用普通js对象作为道具

在这里,它更像是一个人的偏好,但是因为你想让你的组件尽可能地保持愚蠢,为什么他们会知道他们的道具是Immutable对象并且知道如何处理它们?

一般情况下,使用props中的Immutable.js来进行参考等式检查很有诱惑力,这样可以在浅层比较道具时使用,以避免不必要的渲染。当你拥有非常嵌套的道具时它非常方便我认为非常嵌套的道具是一个坏主意。尽量使您的组件道具尽可能保持平坦,这样可以减少与数据架构的耦合,并且可以重复使用。

修改

正如Raj R在评论中所述,您可以使用一些gettersselectors作为不可变商店和哑巴组件之间的桥梁。这是完全合理的,因为根据定义,gettersselectors与您的商店紧密耦合,因此他们可以接收处理不可变数据并通过普通的js对象将其打开到外部世界,这些对象将由您的哑巴使用组件。