Хранилище (Store)

Хранилище содержит все дерево состояний вашего приложения. Единственный способ поменять состояние внутри него - это направить действие (action) на него.

Хранилище - это не класс. Это просто объект с некоторыми методами в нем. Чтобы его создать, передайте вашу корневую функцию редьюсера в createStore

Примечания для пользователей Flux

Если вы пришли из Flux, то есть одно важное отличие, которое необходимо понять. Redux не имеет Диспетчера (Dispatcher) или поддержки множественных хранилищ. Вместо этого здесь только одно хранилище, с одной корневой функцией редюсера. Если ваше приложение растет, то вместо добавления хранилищ, вы разделяете корневой редьюсер на более мелкие редьюсеры, независимо работающие в разных частях дерева состояний. Для их объединения может помочь combineReducers. Можно провести аналогию с тем, что есть один корневой компонент в приложении React, но состоящий из множества маленьких компонентов.

Методы хранилища

Методы хранилища

getState()

Возвращает текущее состояние вашего приложения. Оно равно последнему возвращенному значению из редьюсера хранилища.

Возвращает

(Любое): Текущее состояние вашего приложения.


dispatch(action)

Отправляет действие. Это единственный способ изменить состояние.

Функция редьюсера хранилища будет вызвана с текущим getState() результатом и переданным действием (action) синхронно. Возвращенное значения будет содержать следующие состояние. Оно будет возвращено из getState() сразу же и подписчики будут немедленно уведомлены.

Примечания для пользователей Flux

Если вы попытаетесь вызвать dispatch изнутри редьюсера, то возникнет ошибка "Редьюсеры не могут отправлять действия". Это аналогично ошибке во Flux "Нельзя отправлять в середине отправки", но это не вызвано проблемами связанными с ним. Во Flux отправлять запрещено пока Хранилище не обработает действие и запустит обновление. Это сделано для того, чтобы сделать невозможным отправку действий из хуков жизненного цикла компонент или других слабых мест.

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

Параметры

  1. action (Object): Простой объект описывающий изменения, которые имеют смысл для вашего приложения. Действия являются единственным способом получения данных из хранилища, т.ч. любые данные, будь то события UI, сетевые колбеки или другие источники, такие как вебсокеты, нуждаются, в конечном счете, быть направлеными как действия. Действия должны иметь поле тип (type), для того чтобы указывать какой тип действия будет выполнен. Типы могут быть определены, как константы и импортироваться из других модулей. Лучше всего использовать строки (strings) для типов, чем символы (Symbols), потому что строки сериализуемы. Если вам интересно, то посмотрите Flux Standard Action рекомендации о том, как действия могут быть построены.

Возвращает

(Object): Посланное действие

Заметки

Реализация «ванильного» хранилища, который вы получите, вызывая createStore поддерживает только простые объекты действий, передаваемые непосредственно редьюсеру.

Однако, если вы оборачиваете createStore в applyMiddleware, посредники (middleware) могут интерпретировать действия по-разному и обеспечивать поддержку для отправки асинхронных действий (async actions). Асинхронных действия - это обычно асинхронные примитивы, типа Промисов (Promises), Наблюдателей (Observables), или преобразователей (thunks).

Посредники созданы сообществом и не поставляются с Redux по умолчанию. Вы должны явно установить пакеты, такие как redux-thunk или redux-promise для их использования. Вы также можете создать свои собственные посредники.

Чтобы узнать, как описать асинхронный вызовы API, для чтения текущего состояния внутри генераторов действий, выполнения побочных эффектов или для выполнения последовательности цепочек, посмотрите пример использования applyMiddleware.

Пример

import { createStore } from 'redux';
let store = createStore(todos, ['Использовать Redux']);

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  };
}

store.dispatch(addTodo('Прочитать документацию'));
store.dispatch(addTodo('Прочитать о посредниках'));

subscribe(listener)

Добавляет слушателя. Это будет вызываться каждый раз, когда действие отправлено и некоторая часть дерева состояния могла потенциально измениться. Вы можете затем вызвать getState(), для того, чтобы прочитать текущее состояние дерева хранилища внутри обратного вызова.

Это низкоуровневое API. Скорее всего, вместо использования этого напрямую, вы будете использовать React (или другое) связки. Если вы чувствуете, что обратный вызов должен быть вызван с текущим состоянием, вы можете преобразовать хранилище в Observable или написать свой observeStore.

Для отписки слушателя, вызовите функцию возвращенное subscribe.

Параметры

  1. listener (Function): Колбэк будет вызван в любое время когда действие может быть отправлено и состояние может быть изменено. Вы можете вызвать getState() внутри колбэка, для того чтобы прочитать текущее состояние. Разумно ожидать, что редьюсер хранилища - это чистая функция, т.ч. вы можете сравнить ссылки на некоторый глубокий путь в состоянии, чтобы узнать, изменилось ли его значение.
Возвращает

(Function): Функция которая отписывает слушателя.

Примеры
function select(state) {
  return state.some.deep.property;
}

let currentValue;
function handleChange() {
  let previousValue = currentValue;
  currentValue = select(store.getState());

  if (previousValue !== currentValue) {
    console.log('Некоторое глубокое вложенное свойство измененное от ', previousValue, 'к', currentValue);
  }
}

let unsubscribe = store.subscribe(handleChange);
handleChange();

replaceReducer(nextReducer)

Заменяет редьюсер, который в настоящее время используется хранилищем, чтобы вычислить состояние. Это усовершенствованное API. Вам возможно понадобится это, если ваше приложение реализует разделение кода и вы хотите загрузить некоторые редьюсеры динамично. Вам также это может понадобиться, если вы реализуете горячий механизм перезагрузки для Redux.

Параметры

  1. reducer (Function) Следующий редюсер для хранилища который будет использован.