Redux: Вызов store.getState() в функции редуктора - это анти-шаблон?

Мне интересно, иногда у меня есть редуктор, которому нужна информация от другого редуктора. Например, у меня есть этот редуктор:

import * as ActionTypes from '../actions/action_type_constants';
import KeyCode from 'keycode.js/index';
import {store} from "../index";
import {mod} from "../pure_functions";

export function selectedCompletion(state = 0, action) {
  if (action.type === ActionTypes.arrowKeyPressed) {
    const completionsLength = store.getState().completions.data.length;
    if (action.keyCode === KeyCode.UP) {
      return mod(state - 1, completionsLength);
    } else if (action.keyCode === KeyCode.DOWN) {
      return mod(state + 1, completionsLength);
    }
  }
  return state;
}

Я вызываю store.getState во второй строке функции, потому что иначе я не могу правильно определить индекс.

Я мог бы, вероятно, реорганизовать этот и другой редуктор, чтобы он стал одним большим редуктором, но для удобства чтения я бы предпочел этот вариант.

Я не уверен, если я каким-то образом столкнулся с проблемами, если я использую этот шаблон вызова store.getState() в редукторе.

Ответ 1

Да, это абсолютно анти-паттерн. Функции редуктора должны быть "чистыми" и основываться только на их прямых входах (текущее состояние и действие).

Redux FAQ обсуждает этот вид проблемы в FAQ по разделению состояния между редукторами. По сути, вы должны либо написать некоторую пользовательскую логику редуктора, которая передает требуемую дополнительную информацию, либо добавить больше информации в ваши действия.

Я также написал раздел для документов Redux, озаглавленный Structuring Reducers, в котором обсуждается ряд важных концепций, связанных с логикой редуктора. Я бы посоветовал вам прочитать это.

Ответ 2

Требуемый шаблон является примером композиции, поскольку вы готовите новое состояние на основе других существующих состояний из другого домена (в смысле доменов-редукторов). В документации Redux приведен пример в разделе " Вычисление производных состояний".

Обратите внимание, что их образец, однако, объединил состояния в контейнере, а не в редукторе; все же кормя компонент, который нуждается в этом.

Ответ 3

Для тех, кто заходит на эту страницу, задается вопросом, как обновить свои большие приложения до версии Redx 4.0 без изменения полного управления состоянием, потому что getState и т.д. Были запрещены в редукторах:

Хотя я, как и авторы, не одобряю этот антипаттерн, когда вы понимаете, что они запретили использование этих функций без каких-либо технических причин и отказа, оставив людей без обновлений, которые имеют несчастье иметь кодовые базы, которые широко используют это antipattern... Ну, я сделал запрос на слияние, чтобы добавить отказ с тяжелой охраной, но он был сразу же закрыт.

Поэтому я создал форк редукса, который позволяет отключить запреты при создании магазина:

https://www.npmjs.com/package/free-redux