成本不可变的操作

时间:2018-04-09 09:45:45

标签: javascript reactjs redux immutability

我的redux状态中的数据有~100,000个json记录(每条记录有8个键值对)。

我在客户端编写了一个逻辑,每30秒刷新一次这个数据(每30秒我调用一次服务器来获取要删除的记录和要添加的记录)。

我在reducer函数中执行此处理,为此我编写了一个方法" mergeUpdates"迭代通过state.data对象标识要删除的内容和要插入的内容。

我使用来自immutable的fromJs(state.data).toJs来克隆state.data并进行更新(state.data不是不可变的)。但是这个克隆结果是非常昂贵的操作(对于100,000条记录大约需要2秒)因此我删除了克隆并开始修改state.data本身,导致"赋值给函数参数" lint错误,因为我正在修改传递给函数的数据。

initialState = {
  data: {}
}

doSomething(state, change) {
    // iterates on state and updates state
    state = doSomethingElse();
    return state;
}

mergeUpdates(state, change) {
   // some logic
   state = doSomething(state, change)

   // some more logic
   return state;
}


export default function (state=initialState, action) {
    switch (action.type) {
        case REFRESH: {
            return mergeUpdates(state.data, action.data)
        }
    }
}

处理此类情况的最佳做法是什么,我应该将状态分配给" mergeUpdates"和" doSomething"方法并返回一个新的引用,或使我的数据在状态内变为不可变或其他什么?

例如:这被认为是一种好习惯吗?

doSomething(state, change) {
    let newState = state; 

    // process change and return newState

    return newState; 
}

mergeUpdates(state, change) {
    let newState = state;

    // apply change on newState 
    newState = doSomething(newState, change);

   // return newState
   return newState;

}

2 个答案:

答案 0 :(得分:1)

Redux本身不强制用户使用普通对象进行状态管理。您可以使用不可变对象来存储数据,您唯一需要做的就是像上面那样通过fromJS重新创建全新状态。 此外,必须在整个应用程序中使用immutable。实际上,如果您的数据结构不复杂而不是繁琐的不可变,我建议您使用扩展运算符进行数据修改。 (对我来说,树下三层以上很复杂)。

答案 1 :(得分:1)

您应该尽可能避免使用Immutable.js的toJS()fromJS()函数。根据其作者Lee Byron,this are the most expensive operations in the library

我建议找一个不同的方法。一些建议:

  • 如果您的数据已在Immutable.js中,请使用其提供的其他功能来帮助更新该数据(例如Map.withMutations()
  • 如果该数据不在Immutable.js中,或者您想避免使用它,您可能需要查看one of the many immutable update libraries available,其中一些专门用于帮助将新值合并到现有数据中结构。