为什么我的redux商店不是一成不变的?

时间:2017-04-12 16:23:20

标签: reactjs react-redux immutable.js

我目前正在使用react-redux和Immutable.js。我刚刚意识到我店里的每个字段都是不可变类型。但是,当我在商店中控制.log时,它实际上是一个对象,其中值是不可变类型。商店本身仍然是一个对象。

我创建了一个名为configStore的自定义函数,我在其中使用compose添加中间件,devtools等。然后我调用configStore来实际创建我的商店,它采用一个空对象作为初始状态。当我在我的商店中安装console.log时,我会得到这样的结果:

Object {
  keyA: Map(),
  keyB: OrderedMap(),
  ...
}

这似乎与我在整个应用程序中所做的事情相矛盾,选择器会在整个州内获取商店中的数据。例如,我会执行(state) => state.keyA.getIn(nestedKey, furtherNestedKey)之类的操作。 getIn()是一个ImmutableJS API。

这让我几个让我担心的问题:

  • 如果state是一个对象,如我在console.log商店中所示,那么Immutable如何与它进行交互?

  • 是否有非不可变存储(包含不可变数据类型),无法使用Immutable和React-redux?

1 个答案:

答案 0 :(得分:0)

Immutable仅提供最常见的数据结构集的不可变版本,例如ListMapSet等。它不直接与状态交互,而是您可以在状态的某些属性中使用其数据结构,例如,存储对象的集合。您应该使用Immutable,这样您就可以在不改变状态的情况下操纵这些数据结构。以下面的代码为例,假设您有一个返回文章数组的操作:

import Immutable from 'immutable';

reducer = (state = {
  articlesLoaded: false,
  articles: Immutable.List(),
}, action) => {
  switch(action.type) {
    case "GET_ARTICLES":
      return { 
        ...state, 
        articlesLoaded: true, 
        articles: Immutable.List(action.articles) 
      };
    default:
      return state;
  }
}

使用Immutable的目的纯粹是方便,因为它可以更容易地避免数据结构中的突变。当然,您可以拥有一个不是不可变数据结构的商店,实际上这是最常见的用例。重要的是要注意对象的不变性并不取决于对象本身,而是取决于你操作它的方式(你没有,你创建一个新的),所以你也可以在使用Immutable时改变状态如果你真的搞砸了。

如果你不想继续使用Immutable redux-immutable有一个使用不可变数据结构的combineReducers的修改版本,那么你可以将整个状态定义为Immutable.Map