Встроенная альтернатива Redux с помощью React Context и хуков

Встроенная альтернатива Redux с помощью React Context и хуков

От автора: так как новый React Context API был представлен в версии 16.3.0, у многих людей возникла мысль, достаточно ли хорош этот API, чтобы пересмотреть вопрос об использовании Redux. Мне было интересно то же самое, но я с тех пор больше не следил за данной темой, даже после выхода 16.8.0 с Hooks API. Я стремлюсь к использованию популярных технологий, не понимая всего спектра проблем, которые они решают, поэтому я слишком привык к Redux.

Ну, так получилось, что я подписался на новостную рассылку Кента С. Доддса и заметил несколько электронных писем на тему управления контекстом и состоянием, поэтому я начал читать… и читал дальше… и прочитал еще 5 постов в блоге, пока у меня что-то не щелкнуло.

Чтобы понять все основные концепции, стоящие за этим, мы создадим кнопку, которая выбирает папины шутки из icanhazdadjoke и отображает их. Этот минимальный пример — все, что нам нужно.

Чтобы подготовиться, давайте начнем с двух, казалось бы, случайных советов. Сначала позвольте представить вам моего друга console.count:

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

Мы добавим вызов console.count к каждому компоненту, чтобы увидеть, сколько раз он рендерится. Довольно круто, а?

Во-вторых, при повторной визуализации компонента React он не будет повторно отображать содержимое, переданное в качестве его дочерних элементов:

После нескольких нажатий на кнопку вы должны увидеть следующий вывод в консоли:

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

Button должен получить эмиттера действия, который выбирает шутку папы, DadJoke должен получить состояние и App должен предоставить их с использованием провайдера контекста.

Мы создадим пользовательский компонент с именем DadJokeProvider, который будет внутренне управлять состоянием и помещать его дочерние элементы в провайдер контекста. Помните, что обновления его состояния не будут повторно отображать все приложение из-за дочерней оптимизации React, о которой мы упоминали ранее.

Итак, давайте создадим файл с именем contexts/dad-joke.js:

Давайте также экспортируем два хука для использования значения этого контекста:

Теперь мы уже можем реализовать это:

Та-дам! Благодаря API, который мы создали с помощью хуков, нам больше не придется вносить какие-либо изменения в этот файл!

Давайте начнем добавлять функционал в файл контекста, начиная с управления состоянием DadJokeProvider. В то время как мы могли бы просто использовать хук useState, давайте вместо этого будем управлять состоянием с помощью редуктора, просто чтобы добавить то приятное касание излишнего уровня, которое мы знаем и любим из Redux:

Теперь мы можем передать этот редуктор в хук useReducer и получить папину шутку из API:

Это должно сработать! Нажатие на кнопку теперь должно выбрать и вывести папины шутки! Давайте проверим консоль:

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

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

Теперь мы вступаем на территорию ссылочного равенства, поэтому быстрый обзор:

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

Здесь мы создаем новый объект при каждом рендеринге, но это неизбежно, потому что новый объект состояния будет создаваться каждый раз, когда мы отправляем действие, поэтому просто невозможно запомнить это значение.
Такое чувство, что история на этом заканчивается, верно?

Если мы посмотрим на нашу функцию fetchDadJoke, единственное, что она использует из внешней области видимости, это dispatch? Хорошо, я открою вам небольшой секрет о функциях, создаваемых useReducer и useState. Для краткости я приведу в качестве примера useState:

Нажмите кнопку несколько раз и посмотрите на консоль:

Вы заметите, что setCount это точно такая же функция для каждого рендеринга! Это также относится к нашей функции dispatch.

Это означает, что наша функция fetchDadJoke не зависит от чего-либо, что изменяется со временем, и не зависит ни от каких других эмиттеров действий, поэтому объект actions нужно создавать только один раз, при первом рендеринге:

Теперь, когда у нас есть запомненный объект действий, можем ли мы оптимизировать значение контекста? Ну, нет, потому что независимо от того, насколько мы оптимизируем значения объекта, каждый раз из-за этого нужно создавать новое состояние. Однако что если объект actions просто сбросит этот контекст в новый? Кто сказал, что у нас есть только один?

Мы можем объединить оба в нашем DadJokeProvider:

и настроить хуки:

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

Теперь вы внедрили собственное оптимизированное решение для управления состоянием! Вы можете создавать различные провайдеры, используя этот двухконтекстный шаблон для создания приложения, но не только. Вы также можете визуализировать один и тот же компонент провайдера несколько раз ! Что-о-о-о!? Да, попробуйте, выполните рендеринг DadJokeProvider в нескольких местах и наблюдайте, как ваше решение для управления состоянием легко масштабируется.

Дайте волю своему воображению и пересмотрите то, что вам действительно нужно для Redux.

Спасибо Кенту Доддсу за то, что он написал о двухконтекстном шаблоне, я этого больше нигде не видел и считаю, что это изменит правила игры.

Автор: Matija Marohnić

Источник: https://silvenon.com

Редакция: Команда webformyself.

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

ReactJS: основы

Изучите основы ReactJS и создайте ваше первое приложение на ReactJS

Смотреть

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий