Есть много способов передать состояние через дерево компонентов, например, проп-бурение, использование библиотек управления состоянием, таких как 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)})
Итак, каждый раз, когда мы нажимаем кнопку увеличения счетчика, счетчик обновляется в магазине, и мы видим обновленное значение счетчика в нашем приложении для реагирования.