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

Стор

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

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

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

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

getState()

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

Возвращает

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

dispatch(action)

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

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

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

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

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

Параметры

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

Возвращает

(Object)
Посланный экшен

Заметки

«Ванильная» реализация стора, полученная вызовом createStore, поддерживает только простые объекты экшенов, передаваемые непосредственно редьюсеру.

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

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

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

Пример

import { createStore } from 'redux';
const store = createStore(todos, ['Use Redux']);

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

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

subscribe(listener)

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

Вы можете вызвать dispatch() из слушателя изменений со следующими оговорками:

  1. Слушатель должен только вызывать dispatch() либо в ответ на действия пользователя, либо в определенных условиях (например, отправление экшена, когда стор имеет конкретное поле). Вызов dispatch() без каких-либо условий технически возможен, однако это приводит к бесконечному циклу, так как каждый вызов dispatch() обычно снова вызывает слушателя.

  2. Подписки снимаются непосредственно перед каждым вызовом dispatch(). Если вы подписываетесь или отменяете подписку во время вызова слушателей, это не будет иметь никакого отношения к dispatch(), который в настоящее время выполняется. Однако следующий вызов dispatch(), вложенный или нет, будет использовать более свежий снимок списка подписки.

  3. Слушателю не следует ожидать всех изменений состояния, поскольку состояние могло быть обновлено несколько раз во время вложенной dispatch() до вызова слушателя. Тем не менее, гарантировано, что все подписчики, зарегистрированные до запуска dispatch(), будут вызываться с самым последним состоянием к моменту его выхода.

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

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

Параметры

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
    );
  }
}

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

replaceReducer(nextReducer)

Заменяет редьюсер, который в настоящее время используется стором, чтобы вычислить состояние.

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

Параметры

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