Есть много способов передать состояние через дерево компонентов, например, проп-бурение, использование библиотек управления состоянием, таких как zustand, redux-toolkit, API-интерфейс react-context и т. д. Мы рассмотрим, как настроить redux toolkit в реагировать, все, от установки до фактического использования для управления нашим состоянием.

Зачем вообще использовать библиотеки State Management?

Ну, на самом деле вам не «нужны» какие-либо библиотеки управления состоянием для использования состояний, объявленных в компонентах родительского уровня, потому что вы можете передать состояние от самого верхнего родительского компонента всем дочерним компонентам, которые используют это состояние, передав состояние через свойства.

import React,{useState} from "react";

export default const App = (){
const [count,setCount] = useState(0);

return
(
// The ChildComponent will have access to the count state, and when count is updated
//, it will also update in the child component
<ChildComponent count={count} /
)
}

. Если у вас небольшое количество общих компонентов, то это не будет проблемой, а вместо этого рекомендуется использовать проп-бурение для передачи состояния, поскольку это снижает сложность кода, и вам нужно писать гораздо меньше шаблонного кода. Но если ваше приложение хоть немного сложное и имеет много движущихся частей, то настоятельно рекомендуется использовать библиотеку управления состоянием, так как кодовая база становится неподдерживаемой и становится трудно вносить изменения в ваш код.

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

npx create-react-app appname

cd ./appname

npm start

После того, как вы запустите команду npm start, это должно привести вас к этому экрану на локальном хосте 3000. Это означает, что вы успешно создали и инициализировали реагирующее приложение.

Следующим шагом будет установка необходимых пакетов из NPM,

Запустите эти команды в своем терминале ->

npm i @redux-toolkit --save
npm i react-redux --save

Выполнение этой команды установит redux-toolkit и react-redux в модули вашего узла, а также обновит package.json.

Теперь, когда мы установили все наши зависимости, пришло время создать наш первый «магазин».

внутри папки «src» создайте новый файл с именем store.js.

Давайте создадим наш Магазин:

Объяснение:

Импортируйте «configureStore» из «@redux/toolkit». В основном «configureStore» создает хранилище для хранения всех глобальных состояний. Но вы не можете напрямую изменять значения в хранилище, потому что Redux построен на принципах неизменности, поэтому, если мы хотим обновить значения в хранилище, нам нужно создать новое состояние, которое является копией старого состояния с обновленными значениями и вернуть это состояние в магазин. Для таких действий модификации мы создаем что-то, называемое «Редукторы».

Концепция изменчивости и неизменности

«Мутабельный» означает «изменчивый». Если что-то «неизменно», это никогда нельзя изменить. Объекты и массивы JavaScript по умолчанию являются изменяемыми. Если я создаю объект, я могу изменить содержимое его полей. Если я создаю массив, я также могу изменить его содержимое.

Это называется изменением объекта или массива. Это тот же объект или ссылка на массив в памяти, но теперь содержимое внутри объекта изменилось.

Чтобы постоянно обновлять значения, ваш код должен создавать копии существующих объектов/массивов, а затем изменять копии.

Мы можем сделать это вручную, используя операторы расширения массива/объекта JavaScript, а также методы массива, которые возвращают новые копии массива вместо изменения исходного массива:

В более ранней версии Redux, если вы хотели постоянно обновлять хранилище, вам нужно было использовать этот метод, и это могло стать очень утомительным. С помощью redux-toolkit, использующего Immer внутри, вы можете написать это гораздо более подробно.

const obj1 = {value : 0};

const objCopy = {...obj1,{value :1}}

Давайте создадим наш самый первый редуктор:

Объяснение:

Приведенный выше фрагмент кода может показаться очень пугающим и запутанным, но не волнуйтесь, на самом деле он очень и очень прост. Давайте начнем сверху, мы импортируем 2 вещи из библиотеки redux-toolkit, createAction и createReducer. Сначала давайте определим, что такое действие:

Действие — это событие, которое запускает редьюсер для внесения изменений в ваш магазин. Эти изменения могут быть любой логикой, например, добавление новых сообщений в состояние публикации в вашем магазине, удаление/удаление сообщений по идентификатору в состоянии публикации и т. д. Таким образом, исходя из приведенного выше определения, действие должно выполнять две вещи:

1) -> Укажите, какой тип логики должен выполняться в редюсере (например, добавление новых элементов или удаление существующих элементов)

2) -> Предоставьте данные для выполнения этой логики, например, если мы хотим выполнить действие по добавлению нового сообщения, наряду с типом действия («добавить новое сообщение»), нам также необходимо предоставить данные, относящиеся к сообщению, такие как заголовок сообщения и содержание сообщения. Редьюсер смотрит на тип действия и забирает с собой полезную нагрузку, а в состояние добавляет новый пост

builder.addCase(ADD_POST,(state,action) => {
  state.push(
{
  postTitle : action.payload.title,
  postContent: action.payload.content
}
)
})

createReducer принимает начальное значение и функцию, которая определяет все различные варианты действий. Не беспокойтесь о нотации builderCase, вы к ней привыкнете! Существует более аккуратный способ написать ваш createReducer без использования нотации buildercase, то есть с использованием нотации Map Object, вот пример:

Итак, после того, как мы закончили создание наших действий и редуктора, нам нужно сказать нашему хранилищу использовать этот редюсер. Итак, вернемся к store.js

Что ж, теперь, когда мы настроили наш магазин, создали наш редюсер, который изменяет состояние нашего хранилища, а также мы создали действия, которые запускают определенную логику в нашем редукторе. Вам может быть интересно, как мы на самом деле используем состояние нашего хранилища и изменяем состояние при нажатии кнопки в нашем реагирующем приложении. Ниже приведен код для того же с помощью хука useReducer() в реакции.

Объяснение:

Мы просто используем хук «useReducer», чтобы получить текущее состояние и метод отправки. Состояние относится к значениям, хранящимся в хранилище, например к нашей переменной count. когда состояние хранилища изменяется/обновляется, переменная состояния здесь обновляется и предоставляет обновленное состояние хранилища нашему реагирующему приложению.

Метод Dispatch() — это то, что позволяет нам выполнять и отправлять действия редюсеру для внесения изменений в хранилище.

Напомним, что мы создали 2 действия в нашем файле reducer.js, INCREMENT_COUNT и DECREMENT_COUNT, мы можем передать эти действия в нашу диспетчерскую функцию, и в зависимости от типа отправляемого действия в нашем редьюсере выполняется некоторая логика. например, если мы отправим INCREMENT_COUNT, то редюсер увеличит значение счетчика на 1. Эти действия также могут брать с собой некоторую полезную нагрузку, которую можно использовать для внесения изменений в состояние.

//without payload
dispatch(INCREMENT_COUNT())
//with payload
dispatch(ADD_TODO({title:"new title",desccription:"new desc"}))

//This payload can be used in the reducer

builder.addCase(ADD_TODO,(state,action) => {state.push(action.payload)})

Итак, каждый раз, когда мы нажимаем кнопку увеличения счетчика, счетчик обновляется в магазине, и мы видим обновленное значение счетчика в нашем приложении для реагирования.