повторно выбрать объект из редукции - PullRequest
0 голосов
/ 02 августа 2020

Я использую повторный выбор, и у меня проблемы с выбором состояния в моем магазине.

Мой магазин 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.view и state.boxs.space. Компонент 3 использует state.boxs.options. Когда Component3 меняет значение state.boxs.options (действие отправки CHANGE_OPTIONS в моем редукторе). Компонент2 и Компонент1 будут повторно отрисованы. Как остановить повторный рендеринг? Благодарю за помощь.

1 Ответ

1 голос
/ 02 августа 2020

Я использую это, но когда параметры меняют значение, Component3 не перерисовывается, почему ???

/*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

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

    default:
      return state;
  }
}

Небольшое улучшение, чтобы быть больше DRY, и использовать мемоизацию, чтобы создать начальный селектор ввода для выбора вашего объекта state.boxs, который будет использоваться в качестве ввода для других селекторов.

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,
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...