从 redux 中重新选择对象

reselect object from redux

我使用的是 reselect,但我对商店的 select 状态有一些疑问。

我的 redux 商店看起来像:

store = {
  boxs: {
    space: 'large',
    view: 'card',
    options: {
      option01: { id: '01', name: 'Option1', value: true },
      option02: { id: '02', name: 'Option2', value: false },
      option03: { id: '02', name: 'Option3', value: false },
    },
  },
};

这是我的selector.js

const getSpace = createSelector(
  (state) => state.boxs.space,
  (space) => space
);

const getSpaceAndView = createSelector(
  (state) => state.boxs,
  (boxs) => ({
    space: boxs.space,
    view: boxs.view,
  })
);

const getOptions = createSelector(
  (state) => state.boxs,
  (boxs) => ({ ...boxs.options })
);

// I use this but when options change value, Component3 not re-render, why ???
/*const getPreferences = createSelector(
  (state) => state.boxs,
  (boxs) => boxs.options
);*/

我的减速器

reducers = (state = initState, action) => {
  switch (action.type) {
    ...
    case 'CHANGE_OPTIONS':
      const { key, val } = action; // key = 'option01' | 'option02' | 'option03', value = true || false
      const newState = { ...state };
      newState.boxs.options[key].value = val;
      return newState;
    default:
      return state;
  }
}

我有 3 个组成部分。组件 1 使用 state.boxs.space。组件 2 使用 state.boxs.viewstate.boxs.space。组件 3 使用 state.boxs.options。当 Component3 更改 state.boxs.options 值时(我的减速器中的调度操作 CHANGE_OPTIONS)。 Component2 和 Component1 将重新渲染。如何停止重新渲染?感谢您的帮助。

I use this but when options change value, Component3 not re-render, why ???

/*const getPreferences = createSelector(
  (state) => state.boxs,
  (boxs) => boxs.options
);*/

reducer 应该是一个纯函数。您看起来正在改变状态对象。您应该浅复制 all 您将要更新的数据。

reducers = (state = initState, action) => {
  switch (action.type) {
    ...
    case 'CHANGE_OPTIONS':
      const { key, val } = action; // key = 'option01' | 'option02' | 'option03', value = true || false

      return {
        ...state,
        boxs: {
          ...state.boxs,
          options: {
            ...state.boxs.options,
            [key]: {
              ...state.boxs.options[key],
              value: val,
            },
          },
        },
      };

    default:
      return state;
  }
}

为了更加 DRY 和利用记忆化,一个小的改进是创建一个初始输入 select 或者 select 您的 state.boxs 对象用作另一个输入 select或

const boxsSelector = state => state.boxs;

const getSpace = createSelector(
  [boxsSelector],
  boxs => boxs.space,
);

const getSpaceAndView = createSelector(
  [boxsSelector],
  boxs => ({
    space: boxs.space,
    view: boxs.view,
  })
);

const getOptions = createSelector(
  [boxsSelector],
  boxs => boxs.options,
);