Как Redux управляет сложным состоянием

Redux - это библиотека JavaScript для управления и поддержания состояния приложения, которая используется вместе с другими фреймворками, такими как React. Понимание того, как работает Redux, может быть непростым. Цель этого руководства - разобрать некоторые ресурсы, которые мы получаем от Redux, а также объяснить терминологию, связанную с ними.

Установите установку и внедрение Redux

Давайте сначала сгенерируем приложение React с именем redux-practice со следующим:

npx create-react-app "redux-practice"

Целью этого сгенерированного приложения является тестирование Redux, в первую очередь из src/index.js.

Нам также необходимо установить Redux со следующим:

npm install redux

После установки мы можем импортировать несколько ресурсов из Redux.

Создание Redux Store

Хранилище Redux - это простой объект JavaScript, который предоставляет несколько методов, которые можно вызвать. Состояние приложения содержится в хранилище Redux. Из магазина мы сможем читать и изменять данные в состоянии.

Хранилище Redux должно быть создано в самом начале приложения. В нашем случае это происходит до того, как ReactDOM отобразит приложение. В src/index.js мы можем начать создание магазина, используя именованный экспорт из Redux:

import {createStore} from 'redux'

createStore ()

createStore - функция, вызываемая один раз для создания магазина. Его нельзя вызвать без аргументов. Аргумент, который он принимает, - это функция, известная как reducer, которая возвращает объект, состояние, содержащее данные приложения. В этом примере мы определим reducer в переменной reducerFunction.

const reducerFunction = () => {} 
const store = createStore(reducerFunction)

В reducerFunction первый аргумент, который он принимает, будет представлять состояние, объект. Идеально также установить состояние по умолчанию в аргументе, которым в данном случае будет объект с ключом count и значением 0.

const reducerFunction = (state = {count: 0}) => {
   return state
}

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

В этом руководстве мы сосредоточимся только на getState иdispatch.

Взаимодействие с Redux Store

Чтобы получить доступ к объекту текущего состояния из хранилища, мы вызываем метод в хранилище store.getState(), что-то вроде метода чтения. Если бы мы были console.log(store.getState(), мы бы получили состояние, которое мы определили в reducerFunction.

Действия

Чтобы изменить свойства в хранилище Redux, мы сначала должны создать так называемое действие. Действие - это не что иное, как объект, который отправляется в магазин.

Для объекта первое обязательное свойство - type. Присваиваемое ему значение представляет действие, которое он будет предпринимать. Для этого действия он увеличит счетчик в нашем состоянии. Обычно значение представляет собой строку в верхнем регистре. Объект может принимать дополнительные свойства. В этом примере может потребоваться свойство amount, которое увеличит счетчик на пять.

Давайте создадим функцию, которая вернет объект с этими свойствами и назначит его переменной actionIncrement.

const actionIncrement = () => {
   return {
     type: "INCREMENT",
     amount: 5     
   }
}

Отправлять

Что нам теперь делать с этим действием? Простой вызов actionIncrement() не меняет состояние в нашем магазине. Для этого нам нужно вызвать другой метод в нашем магазине, store.dispatch(actionIncrement()), передав объект, возвращенный из actionIncrement(). Метод .dispatch() позволяет нам отправлять объект действия, и магазин может что-то делать с этой информацией.

При отправке депеши в магазин снова запускается функция createStore(). Действие отправки передается как второй аргумент редуктора reducerFunction.

const reducerFunction = (state = {count: 0}, action) => {
   console.log(action) // {type: "INCREMENT", amount: 5}
   return state
}

Редуктор

В зависимости от переданного действия возвращаемый объект может быть изменен. Условие устанавливается внутри редуктора, чтобы определить, какой объект вернуть. Обычно используется оператор switch. В случае “INCREMENT” мы хотим вернуть объект со свойством count, добавляемым переданной суммой.

Редукторы - это чистые функции, где выход определяется только входом. Он не использует и не изменяет ничего за пределами области действия функции. Никогда не манипулируйте значениями состояния напрямую! Используйте значения состояния для вычисления значений нового состояния.

const reducerFunction = (state = {count: 0}, action) => {
   switch(action.type){
      case "INCREMENT":
      return {
         count: state.count + action.amount
      }
      default:
         return state
      }
}

Работа с несколькими редукторами

По мере расширения приложения потребуются дополнительные свойства и информация. Допустим, мы хотели включить в наше состояние еще одно свойство, comments. Было бы более эффективно, если бы эта информация управлялась другой функцией-редуктором. А пока давайте создадим эту функцию и просто установим состояние в пустой массив.

const commentReducer = (state= []) => {
   return state
}

Однако функция createStore может принимать только одну функцию-редуктор. Вместо передачи функции редуктора можно передать другой метод, который отвечает за объединение нескольких функций редуктора в одно состояние.

Это еще один именованный экспорт из Redux под названием combineReducers. Эта функция принимает аргумент, объект с определенными парами ключ-значение. В нашем примере мы хотим, чтобы ключи countObject и commentsArray были установлены на соответствующие значения.

import {createStore, combineReducers} from 'redux'
const store = createStore(
   combineReducers({
      countObj: reducerFunction,
      commentsArray: commentReducer
   })
)

В конце combineReducers вернет объект, который createStore ожидает в качестве аргумента. Объект, возвращаемый combineReducers, теперь является состоянием.

Краткое описание процесса Redux

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

Ресурсы

Https://rangle.github.io/react-training/redux-intro/

Https://gist.github.com/alexgriff/0e247dee73e9125177d9c04cec159cc6

Вот суть кода:

Заключительные замечания

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