小编典典

如何组成依赖状态的Redux Reducer

reactjs

我正在开发一个React /
Redux应用程序,该应用程序允许将“小部件”添加到页面并在2D空间中进行操作。要求可以一次选择和操作多个小部件。我当前状态树的简化版本如下所示…

{
  widgets: {
    widget_1: { x: 100, y: 200 },
    widget_2: { x: 300, y: 400 },
    widget_3: { x: 500, y: 600 }
  },
  selection: {
    widgets: [ "widget_1", "widget_3" ]
  }
}

我目前有这棵树由2个reducer管理,一个管理widgets状态,另一个管理selection状态。选择状态减少器可以简化为(注意:我也使用Immutable.js)…

currentlySelectedWidgets(state = EMPTY_SELECTION, action) {
  switch (action.type) {
    case SET_SELECTION:
      return state.set('widgets' , List(action.ids));
    default:
      return state
  }
}

这一切似乎都工作得很好,但我现在有一个要求,我正在努力适应这个模型…

为了实现UI,我需要使当前选择具有x / y属性,该属性反映了当前选定的小部件x / y坐标的左上角。一个示例状态可能看起来像…

{
  widgets: {
    widget_1: { x: 100, y: 200 },
    widget_2: { x: 300, y: 400 },
    widget_3: { x: 500, y: 600 }
  },
  selection: {
    x: 100,
    y: 200,
    widgets: [ "widget_1", "widget_3" ]
  }
}

这里的逻辑相当简单,例如,找到min()所有选定的小部件xy值,但是我不确定如何根据化简器组成来处理此问题,因为化简currentlySelectedWidgets器无法访问widgets状态树的一部分。我考虑过…

  • 将reducer合并为一个reducer:这似乎不是一个很好的可扩展解决方案。
  • 随当前动作传递当前的小部件列表:这似乎特别令人讨厌。
  • 寻找一种更好的建模状态树的方法:我曾经考虑过,但是任何其他版本似乎都有其他缺点。
  • 构建一个combineReducers()可以将小部件列表输入到我的currentlySelectedWidgets()reducer中的自定义作为附加参数:我认为这可能是我最好的选择。

我热衷于听到关于其他人如何处理类似情况的其他建议,似乎管理“当前选择”必须是其他人必须解决的普遍状态问题。


阅读 274

收藏
2020-07-22

共1个答案

小编典典

这是Reselect的好用例:

创建一个选择器以访问您的状态并返回 派生 数据。

举个例子:

import { createSelector } from 'reselect'

const widgetsSelector = state => state.widgets;
const selectedWidgetsSelector = state => state.selection.widgets;

function minCoordinateSelector(widgets, selected) {
  const x_list = selected.map((widget) => {
    return widgets[widget].x;
  });

  const y_list = selected.map((widget) => {
    return widgets[widget].y;
  });

  return {
    x: Math.min(...x_list),
    y: Math.min(...y_list)
  };
}

const coordinateSelector = createSelector(
  widgetsSelector,
  selectedWidgetsSelector,
  (widgets, selected) => {
    return minCoordinateSelector(widgets, selected);
  }
);

coordinateSelector现在可以访问你的分xy性质。上面的选择器仅在widgetsSelectorselectedWidgetsSelector状态更改时才会更新,这是一种非常有效的方式来访问您想要的属性,并避免在状态树中重复。

2020-07-22