Перейти к основному содержимому
Неофициальный Бета-перевод

Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →

Хранилище

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

Хранилище — это не класс. Это объект с несколькими методами.

Чтобы создать хранилище, передайте корневую функцию-редюсер в метод configureStore из Redux Toolkit. Он настроит хранилище Redux с оптимальными параметрами по умолчанию. (Если вы ещё не используете Redux Toolkit, можно применять оригинальный метод createStore, но мы настоятельно рекомендуем перейти на Redux Toolkit как можно скорее)

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

getState()

Возвращает текущее дерево состояния приложения. Соответствует последнему значению, возвращённому редюсером хранилища.

Возвращает

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


dispatch(action)

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

Редюсер хранилища будет вызван синхронно с текущим результатом getState() и переданным действием action. Возвращаемое значение станет новым состоянием. Именно оно будет возвращаться getState() в дальнейшем, а подписчики на изменения будут немедленно уведомлены.

Внимание!

Попытка вызвать dispatch внутри редюсера вызовет ошибку "Reducers may not dispatch actions". Редюсеры — чистые функции: они могут только возвращать новое состояние без побочных эффектов (а отправка действий — это побочный эффект).

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

Аргументы

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

Возвращает

(Object): The dispatched action (see notes).

Примечания

The “vanilla” store implementation you get by calling createStore only supports plain object actions and hands them immediately to the reducer.

Если обернуть createStore в applyMiddleware, middleware может интерпретировать действия иначе, обеспечивая поддержку асинхронных действий. Асинхронные действия обычно представляют собой примитивы: Promises, Observables или thunks.

Промежуточное ПО (middleware) создаётся сообществом и не входит в стандартную поставку Redux. Для его использования необходимо явно установить пакеты, такие как redux-thunk или redux-promise. Также вы можете создать собственное промежуточное ПО.

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

Пример

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

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

store.dispatch(addTodo('Read the docs'))
store.dispatch(addTodo('Read about the middleware'))

subscribe(listener)

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

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

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

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

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

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

Для отмены подписки вызовите функцию, возвращаемую методом 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(
'Some deep nested property changed from',
previousValue,
'to',
currentValue
)
}
}

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

replaceReducer(nextReducer)

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

Это продвинутый API. Он может понадобиться при реализации code splitting для динамической подгрузки редюсеров или при создании механизма горячей перезагрузки (hot reloading) для Redux.

Аргументы

  1. nextReducer (Function): Новый редюсер для использования в хранилище.