Redux — это менеджер состояния для библиотеки React.js, но может использовать и другими библиотеками.
Основное предназначение данного модуля — это упростить взаимодействие между частями React — приложения, минуя их зависимость по иерархии.
Как только компоненту необходимо поделиться состоянием с другим компонентом, с которым у него нет отношений родитель-потомок, все становится сложнее. Следующая диаграмма визуализирует эту проблему. В левой стороне вы видите дерево компонентов React. Как только компонент инициирует изменение состояния, это изменение необходимо распространить на все остальные компоненты
Исходя из иллюстрации выше, суть Redux — это централизировать источник приема и отправки потоков между компонентами приложения, при котором все дочерние компоненты обращаются к главному родительскому компоненту, в котором хранится состояние компонентов, который называется Store или объектом Store.
Схема потока
Redux реализует шаблон Flux, который управляет потоком данных в вашем приложении. Компоненты представления подписываются на хранилище и реагируют на изменения.
Компоненты могут отправлять действия, которые описывают, что должно произойти. Редьюсеры получают эти действия и обновляют хранилище
Redux
Состояние Redux хранит все данные приложения в одном дереве объектов, доступном из каждого компонента приложения. В нашем примере состояние содержит небольшой объект JavaScript, как вы можете видеть в следующем фрагменте кода
const state = {
isModalOpen: false,
clipboard: {
commands[]
}
}
Состояние неизменно, и единственный способ изменить его — отправить действие.
state
могут быть любыми и должны быть определены исходя из нужд компонента приложения.Action — действие
Действия — это простые объекты JavaScript, состоящие из обязательного свойства type
для идентификации действия и дополнительной информации payload
. Тип должен быть строковой константой, которая хранится в отдельном модуле для большей ясности. Отсутствуют спецификации именования для реализации объекта с дополнительной информацией. В следующем примере действие устанавливает значение isModalOpen
в false
тип действия — это обычная константа, которая сравнивается редьюсере
const SET_MODAL_OPEN = 'SET_MODAL_OPEN';
действие — это объект, который содержит тип действия type
и некоторая полезная нагрузка payload
const action = {
type: SET_MODAL_OPEN,
payload: false
}
Далее, чтобы вызвать действие или выполнить действие, нужно передать тип действия в функции dispatch()
из Redux
dispatch(action);
Пока что мы можем отправить действие, которое указывает, что состояние должно измениться, но при этом состояние не изменилось, потому что мы не определили редьюсер.
Reducer — редуктор
Редуктор или редьюсер содержит оператор switch
с кейсами для каждого действия и кейс по умолчанию, который возвращает фактическое состояние. Важно отметить, что состояние Redux неизменяемо, поэтому вам необходимо создать копию состояния, которое будет изменено. В наших проектах мы используем предложение оператор объекта spread, но вы также можете использовать Object.assign() . В следующем примере для isModalOpen
задается значение полезной нагрузки действия и сохраняются другие значения состояния
function modalReducer(state, action) {
switch (action.type) {
case SET_MODAL_OPEN:
return {
...state,
isModalOpen: action.payload
})
default:
return state
}
}
Как уже было сказано, редьюсер может либо принять предыдущее состояние, если оно существует, либо необязательное начальное состояние, чтобы определить значение по умолчанию для свойств хранилища. В нашем примере мы настраиваем, что модальное окно изначально должно быть закрыто
const initialState = {
isModalOpen: false
};
function modal(state = initialState, action) {
switch (action.type) {
case SET_MODAL_OPEN:
return {
...state,
isModalOpen: action.payload
})
default:
return state
}
}
Количество редукторов может стать очень большим, поэтому рекомендуется разбивать редукторы на отдельные файлы, оставлять их независимыми и использовать combReducers() для объединения всех редукционных функций в одну, что необходимо для создания хранилища.
Store — хранилище
Мы уже много говорили о хранилище, но не рассмотрели, как создать хранилище. Redux предоставляет функцию createStore() , которая принимает функцию редуктора и, возможно, начальное состояние в качестве аргумента. В следующих фрагментах кода показано, как объединить несколько редюсеров перед созданием хранилища
одно хранилище
import { createStore } from 'redux';
const initialState = {
isModalOpen: false,
clipboard: {
commands[]
}
};
let store = createStore(modalReducer, initialState);
комбинация хранилищ
import { createStore, combineReducers } from 'redux';
const initialState = {
isModalOpen: false,
clipboard: {
commands[]
}
};
const reducer = combineReducers({
clipboardReducer,
modalReducer
});
let store = createStore(reducer, initialState);