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