С Redux мы можем использовать его для хранения данных в центральном месте нашего приложения JavaScript. Он может работать самостоятельно, а также является популярным решением для управления состоянием приложений React в сочетании с React-Redux.
В этой статье мы рассмотрим, как создавать действия, которые можно отправлять в наш магазин с помощью Redux.
Создайте магазин с одним редуктором
Мы можем создать магазин с одним редуктором, создав функцию редуктора. Затем мы можем использовать функцию createStore
Redux для создания хранилища из редуктора.
С магазином мы можем подписаться на него, чтобы получать последние значения, а также отправлять с ним действия для обновления состояния в магазине, передавая его редуктору.
Например, мы можем написать следующий код для создания магазина и выполнения некоторых действий:
import { createStore } from "redux"; function todosReducer(state = [], action) { switch (action.type) { case "ADD_TODO": return [...state, action.todo]; case "REMOVE_TODO": return state.filter(todo => todo !== action.todo); default: return state; } } let store = createStore(todosReducer); store.subscribe(() => console.log(store.getState())); store.dispatch({ type: "ADD_TODO", todo: "eat" }); store.dispatch({ type: "ADD_TODO", todo: "drink" }); store.dispatch({ type: "REMOVE_TODO", todo: "eat" });
В приведенном выше коде мы создали todosReducer
, чтобы получать отправленные действия, а затем манипулировать состоянием, как мы хотим.
У нас есть инструкция switch
, чтобы проверить type
действия и затем действовать соответствующим образом.
Действие type
указано в объекте, который мы передали в метод dispatch
.
Если тип действия - “ADD_TODO”
, то мы вставляем элемент todo
в объект, который есть в аргументе dispatch
, в конец массива и распределяем все старые значения перед ним.
Если тип действия - “REMOVE_TODO”
, мы возвращаем новый массив, исключающий элемент задачи с заданным текстом todo
.
В противном случае мы возвращаем то, что у нас уже есть.
Затем мы используем метод createStore
для создания хранилища, чтобы мы могли вызвать dispatch
для передачи простых объектов для управления данными в хранилище.
Мы также можем subscribe
к нему, а затем вызвать getState()
, чтобы получить последние значения.
Обратите внимание, что мы всегда делаем копию state
, а затем возвращаем с ней что-то новое. Это предотвращает случайные изменения и непреднамеренное изменение объектов.
Создать магазин с несколькими редукторами
В большинстве приложений мы хотим хранить более одного типа данных в нашем магазине. Мы можем сделать это, создав несколько редукторов, а затем использовать функцию combineReducer
из Redux, чтобы объединить их в одно хранилище.
Для этого мы можем написать что-то вроде следующего кода:
import { createStore, combineReducers } from "redux"; function todosReducer(state = [], action) { switch (action.type) { case "ADD_TODO": return [...state, action.todo]; case "REMOVE_TODO": return state.filter(todo => todo !== action.todo); default: return state; } } function countReducer(state = 0, action) { switch (action.type) { case "INCREMENT": return state + 1; case "DECREMENT": return state - 1; default: return state; } } let reducers = combineReducers({ todos: todosReducer, count: countReducer }); let store = createStore(reducers); store.subscribe(() => console.log("todos", store.getState().todos)); store.subscribe(() => console.log("count", store.getState().count)); store.dispatch({ type: "ADD_TODO", todo: "eat" }); store.dispatch({ type: "ADD_TODO", todo: "drink" }); store.dispatch({ type: "REMOVE_TODO", todo: "eat" }); store.dispatch({ type: "INCREMENT" }); store.dispatch({ type: "DECREMENT" });
В приведенном выше коде у нас есть 2 редуктора - todoReducer
и countReducer
.
Мы объединили их в один, вызвав функцию Redux combineReducers
с именем состояния в качестве имени свойства и функцией редуктора в качестве значения.
combineReducers
объединяет все редукторы в один редуктор, поэтому мы можем передать его в createStore
. Мы можем выбрать любое название штата, какое захотим.
Хранилище создается путем передачи большого редуктора, возвращаемого из combineReducers
.
Затем в subscribe
обратных вызовах мы можем использовать store.getState()
для получения всех состояний. Затем мы можем получить задачи со свойством todos
и состояние count
с помощью свойства count
.
В console.log
s должно получиться что-то вроде:
todos ["eat"] count 0 todos ["eat", "drink"] count 0 todos ["drink"] count 0 todos ["drink"] count 1 todos ["drink"] count 0
Это потому, что мы подписались на магазин, а затем получаем состояние от каждого редуктора индивидуально.
Метод dispatch
вызывается так же, как и в примере с одним редуктором.
Мы по-прежнему передаем тип действия и полезную нагрузку, если она есть.
Поскольку dispatch
работает одинаково, независимо от того, сколько редукторов у нас есть в магазине, мы должны убедиться, что никакие 2 действия не имеют одинакового имени.
Примечания
combineReducers
в некоторых случаях вызывает ошибки, чтобы снизить вероятность их совершения.
Это вызовет ошибку, если функция-редуктор не вернет state
, заданный ей в качестве первого аргумента, если действие не распознано.
Кроме того, он никогда не должен возвращать undefined
. Это слишком просто сделать с помощью раннего return
оператора. Следовательно, combineReducers
выдаст ошибку, если мы сделаем это вместо того, чтобы позволить ошибке проявиться где-то еще.
Если ему присвоено state
undefined
, он должен вернуть начальное состояние для конкретного редуктора. Это означает, что начальное состояние не может быть undefined
.
Мы можем указать начальное состояние в качестве аргумента по умолчанию для параметра state
.
Redux проверит эти правила, когда мы будем писать код.
Заключение
Мы можем создать магазин из еще одной функции-редуктора. Единственная разница в том, что мы должны использовать combineReducers
для объединения нескольких редукторов в один большой редуктор, чтобы передать его в createStore
. Мы можем перейти к единственному редуктору прямо в createStore
.
Затем мы можем использовать getState
, чтобы получить последнее возвращенное состояние всех редукторов. Состояния доступны из getState()
, и мы можем получить свойства из возвращенного объекта getState
, чтобы получить эти состояния.
Действия по отправке одинаковы, независимо от того, сколько редукторов у нас в магазине.