В этом руководстве мы рассмотрим, как интегрировать React Hooks в проект React Redux, вообще не меняя код Redux (редукторы и действия).

Чтобы сэкономить время, мы можем начать с простого приложения React Redux вместо того, чтобы создавать его с нуля. Это позволит вам видеть код «до» и «после» рядом и значительно упростит интеграцию для вашего приложения.

Стартовый код:



Использование правильной версии React

Первое, что нам нужно сделать, это убедиться, что у нас есть правильная версия React. На момент написания этой статьи create-react-app не дает вам правильной версии. Итак, что вы можете сделать, это использовать приложение create-response-app, затем перейти в свой package.json и ввести правильную версию. Так что просто измените React и React-dom на версию 16.8. Сохраните файл и удалите папку модулей узла. Запустите npm install, и все готово.

Рефакторинг класса React в React Hook

Итак, первое, что мы сделаем, - это преобразовать компонент класса React в React Hook. Давайте откроем наш файл App.js и превратим его в ловушку, поэтому произведем рефакторинг вашего App.js на следующее:

Так что просто превратите класс в стрелочную функцию и удалите метод рендеринга. Вот и все, вы создали React Hook!

Настройка другого хука

Таким же образом мы можем настроить еще один Hook, который мы настроим в папке с названием Hooks.

Итак, создайте файл hooks_container.js в каталоге hooks и настройте его так:

Хук useState ()

Теперь мы начнем настраивать базовое неглобальное состояние компонента с помощью ловушки useState ().

Хук useState () аналогичен функции React setState (). Он настроен с деструктуризацией массива, где первый элемент в массиве - это значение состояния, а второй элемент - функция для изменения состояния.

Давайте просто создадим базовые кнопки увеличения и уменьшения, чтобы увидеть, как работает функция состояния.

Настройте кнопки так:

Обратите внимание, что нам не нужно использовать ключевое слово «props» или «state» везде, где мы можем просто напрямую использовать имя переменной и функции. Это одна из вещей, с которой так легко работать с React Hooks.

Ваше приложение должно выглядеть примерно так.

И у вас должна быть возможность свободно увеличивать или уменьшать это число.

Теперь, когда у нас есть базовое представление о том, как работает useState (), мы можем перейти к чему-то более сложному.

useReducer () хук

Теперь мы можем приступить к настройке хука useReducer ().

Прежде чем мы сможем использовать хук useReducer (), мы должны сначала настроить редуктор. Фактически действия можно оставить как есть. И изменения, которые мы должны внести в редуктор, очень минимальны. Все, что нам нужно сделать, это изменить операторы экспорта вместо экспорта по умолчанию. Мы должны экспортировать и редуктор, и начальное состояние.

Чтобы сэкономить время, просто создайте новый редуктор с именем hooks_reducer.js в файле редуктора и скопируйте код из Reducer1. У вас должно получиться что-то вроде этого:

Теперь просто импортируйте этот редуктор и его начальное состояние в hooks_container.js. И передайте их оба в хук useReducer ().

Давайте также создадим 2 кнопки, чтобы изменить stateprop1 с false на true, а затем снова на false. И мы также можем создать троичное выражение для отображения текста в зависимости от того, является ли stateprop1 истинным или ложным. Помните, что stateprop1 - это то же самое, что мы настроили в HookReducer1, но мы обновляем здесь, в нашем контейнере.

И мы используем те же ранее существовавшие действия для обновления редуктора. Обратите внимание, в комментариях я оставил два альтернативных метода отправки действий. Все они делают одно и то же. Возврат объекта javascript с типом строки УСПЕХ.

Итак, ваш код должен выглядеть так:

Ваше приложение должно выглядеть так, и вы сможете изменить stateprop1 из контейнера хуков:

Вы заметите одну проблему, когда мы перейдем к другому компоненту: состояние не сохраняется. Это связано с тем, что даже несмотря на то, что мы используем действия и редукторы, состояние по-прежнему является локальным состоянием компонента и недоступно глобально. Чтобы сделать состояние доступным глобально, нам действительно нужно использовать контекст React, который мы настроим в следующих нескольких разделах.

Настройка действий и редуктора

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

Теперь нам нужно настроить действия и типы действий для работы с этим новым состоянием.

Сначала создадим 2 типа действий для stateprop2:

Затем мы можем зайти в наш файл действий и создать 2 создателя действий для обработки этих типов действий.

Наконец, нам нужно настроить наш редуктор, который должен выглядеть так:

Реагировать на контекст

Затем мы должны настроить объект контекста. Просто создайте еще один файл context.js и настройте его так:

Обратите внимание, что prop1 здесь не имеет значения. Мы переопределим это в нашем файле App.js. Мы просто предоставили prop1 для инициализации объекта Context. Весь код для обновления и чтения нашего состояния будет выполнен в файле App.js.

Затем давайте импортируем этот объект контекста в наш файл App.js. Также импортируйте HooksReducer1 и Действия, поскольку мы будем использовать их здесь.

Давайте также настроим useReducer так же, как и раньше.

Затем нам нужно создать 2 функции для отправки создателей действий, которые мы только что создали. Эти функции будут увеличивать и уменьшать stateprop2.

Также нам нужно обернуть наши маршруты компонентом ‹Context.Provider /›. Это то, что позволяет нам иметь глобальное состояние. Компонент ‹Context.Provider /› передает все состояние дочерним компонентам. Поскольку App.js является корневым компонентом, состояние передается каждому компоненту в приложении, что и делает состояние глобальным.

Само состояние содержится в опоре под названием «значение». Все это похоже на компонент ‹Provider /› и свойство store в React-Redux.

Затем нам нужно передать диспетчеризацию состояния и действия как свойства в свойство value. Здесь нам понадобятся 3 свойства: одно для функции, увеличивающей значение нашего состояния, одно для функции, уменьшающей наше значение состояния, и одно для хранения фактического значения состояния.

В целом ваш файл App.js будет выглядеть так:

Я намеренно сохранил все имена функций и свойств, чтобы было легче увидеть, откуда все идет, когда мы используем Context в дочернем компоненте.

Итак, теперь все эти свойства, определенные в опоре значения, могут быть доступны для всех дочерних компонентов, и, следовательно, у нас есть глобальное состояние!

Использование контекста в дочернем компоненте с помощью хука useContext ().

Вернемся к нашему контейнеру хуков, воспользуемся этими функциями и заявим, что мы только что настроили.

Чтобы использовать Context в нашем контейнере хуков, нам сначала нужно импортировать его и передать весь объект Context в хуки useContext. Вот так:

Затем мы можем напрямую получить доступ к свойствам, которые мы установили в опоре значения, напрямую через контекстную переменную.

Помните, что addGlobalValue () - это имя свойства, которое мы предоставили для свойства value в App.js. Это не имя функции для отправки действий или имя функции, которую мы установили в хуке useReducer () в App.js.

Доступ к значению состояния через Context осуществляется следующим образом:

Как и при отправке действий, valueGlobalState - это имя свойства, передаваемое в свойство value. И мы должны получить доступ к stateprop2 с точечной нотацией из свойства valueGlobalState, поскольку valueGlobalState содержит все intialState из HooksReducer1, включая stateprop1.

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

Вы можете использовать этот шаблон, чтобы существенно увеличить масштаб для всего вашего кода Redux.

окончательный код:



Резюме

Итак, вот концептуальное резюме того, как это сделать (требуется базовое знание хуков React):

Действия вообще не нужно менять. Редукторы менять тоже не нужно. Просто экспортируйте и начальное состояние, и редуктор, а не только редуктор. Не используйте «экспорт по умолчанию» внизу файла редуктора.

Импортируйте редуктор и его начальное состояние в корневой файл App.js. Вызовите ловушку useReducer () в корневом файле App.js и сохраните его в переменной. Подобно ловушке useState, первый элемент в деструктурировании массива - это значение состояния, а второй элемент - это функция для изменения состояния. Затем передайте и reducer, и initialState, импортированные в ловушку useReducer (). Импортируйте столько редукторов, сколько хотите, и передайте каждый из них в отдельный хук useReducer ().

Импортируйте действия в App.js как обычно. Действия по отправке тоже точно такие же. Вместо использования функции mapDispatchToProps () вы будете отправлять действия из функции изменения состояния (второй элемент в деструктурировании массива) из вызова ловушки useReducer ().

Настройте и инициализируйте функцию React.CreateContext () в другом файле и импортируйте его в App.js. Затем оберните ваши ‹Routes /› с ‹Context.Provider›. Обычно вам потребуется 3 свойства для каждой части состояния для свойства value в поставщике. 1 для установки нового значения состояния, 1 для перехода в фактическое состояние и 1 для возврата к состоянию по умолчанию.

Затем, чтобы использовать состояние в компонентах, вы сначала импортируете объект контекста из context.js, а затем просто передаете его ловушке useContext () и сохраняете его в переменной с именем «context» или как вам нравится. Затем, чтобы получить доступ к свойству состояния, просто введите имя переменной «context» «.» затем имя свойства, установленного в опоре значения, за которым следует имя свойства, установленного в initialState редуктора. Для отправки действий просто выполните «context» «.» затем назовите имя свойства.

Как только это будет сделано, ваше состояние контекста станет доступным глобально и будет работать с вашим существующим кодом React Redux.

Чтобы получить 100% бесплатную видео версию этого руководства и более подробный контент React Hooks, пожалуйста, посмотрите мой курс Udemy или плейлист на Youtube:

Https://www.udemy.com/react-hooks-with-react-redux-migration

Https://www.youtube.com/watch?v=l8ODM-KoDpA&list=PLMc67XEAt-ywplHhDpoj5vakceZNr8S0B