具有非常大(实际上与状态无关)数据结构的 redux 状态树

redux state tree with a very large (not state related, really) data structure

我有一个运行良好的 redux 应用程序。然而,作为一些数据库查询的结果,存储在状态树中的数据结构之一可以包含 60,000 多个条目。这会大大减慢反应 ui 的反应时间。

我没有涉及大量的 reducer(也许 20 个?)所以我认为 redux-ignore 没有帮助。大数据结构中的数据是只读的,不需要更新。但是,加载它后,在树的不同部分使用不变性助手的 update() 或 merge() 可能会很慢。

这是预期的行为吗?我正在考虑将数据结构移动到 localStorage,但将其存储在状态树中可以使代码简单(并使广泛加载状态变得容易)。

建议?

markerikson:共享 reducer 和数据结构没有坏处!唯一负责状态数据结构部分的reducer是:

export function plotReducer(state={}, action) {
 switch(action.type) {
   case EMIT_PLOT_DATA_REQ:
     return update(state, {$set: action.payload.data });
   default:
     return state;
 }
}

此数据结构在收到时写入状态,然后仅 "read" 由使用它的绘图图表写入。它永远不会被修改。

从服务器接收到的状态中存储的数据对象是一个包含多个对象数组的对象(如 required by recharts 和其他绘图库)。

商店创建于:

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
    reducers,
    initialState,
    composeEnhancers(
    applyMiddleware(
    ReduxPromise,
    ReduxThunk
  )
));

我在索引文件中使用 combineReducers 来创建 rootReducer。

研究过 Immutable.js 我可能只是将数据对象存储在状态之外的自己的结构中。

编辑:插入四条线索。该州一直表现良好。图表库绘制 svg 并且它们在处理大型数据集时速度很慢。我让他们过于频繁地重新渲染 w/o 意识到这一点。根据下面的反馈,我花了一天时间分析应用程序,状态机很好。

您应该考虑为您所在的州使用 Immutable.js。我们已经完成了数据结构与您一样大的应用程序,并且 UI 在初始加载后仍然非常敏感。据我了解,这是因为不可变数据结构的内部尽可能传递对现有对象的引用。因此,当单个条目发生更改时,它会重用 99% 的数据,而不是从头开始重新创建整个对象。这允许状态更改和组件更新非常快。

基本上,如果您的状态对象不是不可变的,则每次状态更改时您都会创建一个全新的状态对象,其中包括重写您的 60k+ 条目。

更新: Mark Erikson 在下面说的是正确的,他说你可以通过使用 "shallow clone" 方法来解决重写问题,并确保你的减速器在一个有效的方法。但是,我还发现这很容易意外搞砸,并可能在您不希望的地方破坏您的优化。 Immutable.js 有助于让您远离这些陷阱,但也有其缺点。查看 Redux 文档中的这篇文章,以帮助确定它实际上是否是您的最佳选择。 http://redux.js.org/docs/recipes/UsingImmutableJS.html

您目前尝试如何更新商店?即使不使用 Immutable.js,标准 "shallow clone" 方法(例如 Object.assign... 对象展开运算符也应该保持现有引用和字段不变。而且,如果你有一个处理 LOAD_THE_LARGE_DATASET 动作的减速器,我希望在剩下的时间里它只是 returns 它现有的状态片不变。

另外,你凭什么说树的这一部分是 "slowing down the reaction time of the React UI"?您是否有一些与此相关的特定基准? "slow"是什么操作?

您可能需要通读 immutable data handling in Redux 上的 Redux FAQ 部分以供参考。