Перейти к содержанию

Глоссарий

Это глоссарий основных терминов в Redux, наряду с их сигнатурами типа. Типы описаны при помощи Flow notation.

Состояние

type State = any;

Состояние (State) (также дерево состояния) — широкое понятие, но в Redux API это, как правило, отсылка к единственному состоянию, которое управляется стором (store) и возвращается getState(). Оно представляет собой все состояние Redux-приложения, которое обычно является объектом с глубокой вложенностью.

Как правило, состояние верхнего уровня — это объект или какая-то другая коллекция вида ключ-значение, например Map, но технически это может быть любой тип. Вместе с тем, вам нужно стараться поддерживать состояние сериализуемым. Не кладите внутрь ничего, что потом не сможете легко превратить в JSON.

Экшен

type Action = Object;

Экшен (Action) — это простой объект, который представляет намерение изменить состояние. Экшены — единственный путь получить данные в сторе. Любые данные, будь то события UI, коллбэки сетевых запросов или любые другие ресурсы как веб-сокеты, должны быть в итоге обработаны, как экшены.

Экшены обязаны иметь поле type, которое указывает тип производимого экшена. Типы также могут быть определены как константы и импортированы из другого модуля. Лучше использовать строки для type, чем Символы, потому что строки сериализуемы.

Вся остальная структура, кроме type, полностью на ваше усмотрение. Если вы заинтересованы, посмотрите Flux Standard Action для рекомендаций как нужно создавать экшен.

Также смотрите асинхронный экшен ниже.

Редьюсер

type Reducer<S, A> = (state: S, action: A) => S;

Редьюсер (Reducer) (так же называемая, как функция-редьюсер) — это функция, которая принимает аккумулятор и значение и возвращает новый аккумулятор. Они используются для редуцирования (сокращения) коллекции значений в единственное значение.

Редьюсеры не уникальны для Redux — они являются фундаментальным понятием в функциональном программировании. Даже большинство нефункциональных языков, как JavaScript, имеют встроенное API для редуцирования. В JavaScript это Array.prototype.reduce().

В Redux, аккумулирумое значение — это объект состояния, а значения, которые должны быть аккумулированы — это экшены. Редьюсеры расчитывают новое состояние, учитывая предыдущее состояние и экшен. Они обязаны быть чистыми функциями — функциями, которые возвращают одинаковый результат для переданных входных данных. Они также не должны иметь побочных эффектов (side-effects). Это то, что обеспечивает интересные возможности, такие как "горячая перезагрузка" (hot reloading) и путешествия во времени (time travel).

Редьюсеры являются наиболее важным понятием в Redux.

Не размещайте вызовы API в редьюсерах.

Функция-диспетчер

type BaseDispatch = (a: Action) => Action;
type Dispatch = (a: Action | AsyncAction) => any;

Функция-диспетчер (Dispatching Function) - это функция, которая принимает экшен или асинхронный экшен и далее может отправить или может не отправить один или несколько экшенов в стор.

Мы должны различать функцию-диспетчер в целом и базовую функцию dispatch, предоставляемую экземпляром стора без всяких мидлваров (middlewares).

Базовая функция dispatch всегда синхронно отправляет экшен в редьюсер вместе с предыдущим состоянием, возвращенным из стора, для вычисления нового состояния. Оно ожидает экшен в виде простых объектов, готовых для использования в редьюсере.

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

Генератор экшена

type ActionCreator = (...args: any) => Action | AsyncAction;

Генератор экшена (Action Creator) - это, совершенно очевидно, функция, которая создает экшен (action). Не следует путать эти два термина - еще раз, экшен - это структура данных, а генератор экшена - это фабрика, которая создает экшен (action).

Вызов генератора экшена только создает экшен, но не выполняет его. Вам нужно вызвать функцию стора dispatch которая на самом деле вызывает изменения. Иногда мы говорим связанные генераторы экшенов имея ввиду функции, которые вызывают генератор экшена и сразу же отправляют его результат соответствующей части стора.

Если генератору экшена надо получить текущее состояние, выполнить вызов API или вызвать побочный эффект, как переход маршрутизации, это должно быть возвращено асихронным экшеном (async action) вместо обычного экшена.

Асинхронный экшен

type AsyncAction = any;

Асинхронный экшен (async action) - это значение, которое передается в вызывающую функцию (dispatching function), но пока не готово для редьюсера. Оно будет преобразовано при помощи мидлвара в экшен или набор экшенов перед отправкой в базовую функцию dispatch(). Асинхронные экшены могут иметь различные типы в зависимости от используемых мидлваров. Они часто являются асихронными примитивами, как промисы (Promise) или thunk, которые не передаются в редьюсер немедленно, а выполняют экшен, только когда операция завершена.

Мидлвар

type MiddlewareAPI = {
  dispatch: Dispatch,
  getState: () => State,
};
type Middleware = (
  api: MiddlewareAPI
) => (next: Dispatch) => Dispatch;

Мидлвар (Middleware) — это функция высшего порядка, которая создает функцию-диспетчер (dispatch function), возвращающую новую функцию-диспетчер. Она часто возвращает асинхронный экшен в экшен.

Мидлвары компонуемы с помощью функции композиции - это полезно для регистрации экшенов, выполнения побочных действий (side effects), таких как, маршрутизация или превращения асинхронного вызова API в серию синхронных экшенов.

См. applyMiddleware(...middlewares) для более детальной информации по мидлварам.

Стор

type Store = {
  dispatch: Dispatch
  getState: () => State
  subscribe: (listener: () => void) => () => void
  replaceReducer: (reducer: Reducer) => void
}

Стор (Store) — это объект, который хранит дерево состояний приложения. В приложении должно быть только один стор, так построение происходит на уровне преобразователя (reducer).

  • dispatch(action) базовая функция отправки (dispatch), описанная выше.
  • getState() возвращает текущее состояние стора.
  • subscribe(listener) регистрирует функцию, которая будет вызвана при изменении состояния.
  • replaceReducer(nextReducer) может быть использован для реализации горячей перезагрузки (hot reload) и разделения кода. Скорее всего Вы не будете использовать ee.

См. store API reference для получения дополнительной информации.

Генератор стора

type StoreCreator = (
  reducer: Reducer,
  initialState: ?State
) => Store;

Генератор стора (Store creator) — это функция, которая создает Redux-стор. Как и в случае с отправляющей функцией, мы должны различать базовый генератор стора, createStore(reducer, initialState) экспортирумый из Redux, от генератора стора, возвращаемого из расширителей стора (store enhancers).

Расширитель стора

type StoreEnhancer = (next: StoreCreator) => StoreCreator;

Расширитель стора (Store enhancer) — это функция высшего порядка, которая создает генератор стора, возвращающий новый, расширенный генератор стора. Это похоже на мидлвар тем, что позволяет вам изменять интерфейс в композиционном стиле.

Расширители стора аналогичны понятию - "компоненты высшего порядка" в React, которые также иногда называются "усилителями компонент".

Поскольку стора является не инстансом, а скорее объектом-коллекцией функций, то копии могут быть запросто созданы и модифицированы, без изменения оригинального стора. Пример в описании compose демонстрирует это.

Скорее всего, вы никогда не будете писать расширитель стора, но вы можете использовать один предоставленный developer tools. Это то, что делает "путешествие во времени" (time travel) возможным без информирования приложения, о том, что происходит. Занятно, что реализация Redux мидлваров сама по себе является расширителем стора.