После моей статьи об интуитивно понятном, свободном от шаблонов решении глобального состояния для React я решил положить в основу концепции реальные данные. Я начал с простого примера приложения React, которое использует Redux для глобального управления состоянием, и преобразовал его в ReactN. В ходе этого процесса я измерил объективные изменения в распределении памяти и размере пакета. Тщательный анализ и исходный код предоставлены на GitHub, но я подведу итоги здесь, а также покажу, насколько легко выполняется преобразование и насколько проще становится отредактированный код.

Вы можете использовать ReactN самостоятельно через reactn on NPM или вносить свой вклад, форк или иным образом следить за репозиторием GitHub с открытым исходным кодом.

Приложение 0️⃣

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

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

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

Приложение Redux 1️⃣

Зависимости 👶👶👶

Для создания нашего приложения Redux нам нужны три пакета: redux, который содержит логику для создания глобального состояния и взаимодействия с ним; react-redux, который содержит логику React и компоненты более высокого порядка для интеграции глобального состояния с приложением React; и redux-thunk, промежуточное ПО Redux для обработки асинхронных изменений состояния.

Инициализация глобального состояния 🎬

Для инициализации глобального состояния мы используем функцию createStore из пакета redux. В него мы передаем желаемые редукторы и промежуточное ПО.

Конечный результат выглядит так:

Функция createStore - это загадка, но я не буду посвящать эту статью обсуждению распространенных жалоб разработчиков на кривую обучения Redux!

Подключение компонентов 🚈

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

Конечный результат выглядит так:

Это очень много кода, чтобы использовать глобальное состояние. Несмотря на то, что пакет react-redux ориентирован на интеграцию Redux с React, я лично не думаю, что вышеупомянутое имеет в виду подход React-first. Но я не буду посвящать эту статью обсуждению распространенных жалоб разработчиков на шаблон Redux!

Хотя этот шаг включает в себя загадочные действия fetchData и incrementX, я включил их в следующий раздел, поскольку они напрямую связаны с записью в глобальное состояние.

Чтение из глобального состояния и запись в него 👁‍🗨

Убрав весь этот шаблон, мы, наконец, можем использовать глобальное состояние! Мы получаем доступ и изменяем состояние через свойства подключенного компонента.

Конечный результат выглядит так:

Помимо действий, сам компонент очень легко читается!

Приложение ReactN 2️⃣

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

Зависимость D̶e̶p̶e̶n̶d̶e̶n̶c̶i̶e̶s̶

Установите пакет reactn. Асинхронного промежуточного программного обеспечения нет. ReactN поддерживает промисы прямо из коробки. Вы можете удалить три вышеупомянутые зависимости Redux и вздохнуть с облегчением, когда ваше приложение упадет на 213 файлов зависимостей и имеет на 13% меньший размер производственного пакета, когда оно вместо этого использует ReactN.

Инициализация глобального состояния 🎬

Первый из громоздких шаблонов, пора инициализировать магазин и установить редукторы. Редукторы и действия в ReactN необязательны. Я включил их сюда только для честного сравнения, поскольку мы используем их в Redux. Если вы обнаружите, что редукторы слишком уж шаблонны, вы можете воздержаться от их использования. Альтернатива без редуктора будет предоставлена ​​позже.

Мы используем setGlobal, чтобы буквально просто установить глобальное состояние. Отлично подходит для инициализации.

Мы используем addReducer, чтобы добавить редуктор. Обратите внимание, что ReactN не использует действия. Мы вызываем редуктор напрямую!

Мы сократили шаблонный код с 640 до 330 при добавлении действий! Подробнее об этом позже - для этого проекта я вообще не стал бы создавать fetchData редуктор. Я включил его сюда только для симметрии с приложением Redux.

Подключение компонентов 🚈

ReactN не использует компоненты более высокого порядка. Чтобы подключить компоненты к глобальному состоянию, вы добавляете в файл один байт.

Я добавил n в конец имени пакета, изменив react на reactn. Вот и все. Ваши Component и PureComponent теперь имеют доступ к глобальному состоянию.

Это было на 728 байтов меньше шаблона! На один HOC для всего приложения меньше и на один для каждого компонента меньше.

Чтение из глобального состояния и запись в него 👁‍🗨

Как мы используем глобальное состояние, если мы не указали ему, какие свойства нам нужны для нашего компонента? Помня о React, ReactN обрабатывает глобальное состояние как переменную-член - точно так же, как вы привыкли использовать с this.state локального состояния.

Компонент выглядит точно так же, за исключением того, что для доступа к глобальному состоянию вы используете переменную-член this.global вместо props. Компоненты более высокого порядка не требуются!

Вот и все! Компонент готов. Он полностью функциональный.

fetchData 🐶

Я уже упоминал, как по-разному обрабатывать действие выборки данных с помощью ReactN, поэтому я подробно остановлюсь здесь. ReactN не ограничивается действиями и редюсерами, как Redux. Глобальная переменная-член состояния ReactN предназначена для того, чтобы вести себя точно так же, как врожденная локальная переменная-член состояния React, и включает аналогичный метод this.setGlobal, который ведет себя как this.setState. Метод setGlobal имеет дополнительные функции поддержки обещаний JavaScript.

Если fetchData не вызывается из нескольких компонентов, он не дает нам возможности называть его редуктором, поэтому я бы вместо этого просто позвонил setGlobal:

Получите index.html, проанализируйте текст, создайте объект состояния и установите его.

Я бы не возражал против того, чтобы incrementX reducer был просто методом в компоненте, который вызывает setGlobal, поскольку он также не распределяется между компонентами.

Последнее сравнение 🏁

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

Раньше: index.js с Redux 🔴

После: index.js с ReactN 💚

Раньше: App.js с Redux 🔴

После: App.js с ReactN 💚

Холодный, твердый факт ⛄

Независимо от того, считаете ли вы, что один метод легче читать, чем другой, одно здесь объективно. Вышеупомянутое приложение в производственной сборке занимает 531 736 байт с использованием ReactN. Его аналог Redux составляет 611 990 байт, что на 15% больше.

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

Заключение 🔚

Если вы хотите внести свой вклад в этот проект, он с открытым исходным кодом на GitHub, и я был бы в полном восторге от дополнительных отзывов сообщества. Если вы хотите поэкспериментировать с этим проектом, просто npm install reactn --save или yarn add reactn.

Если вам понравилась эта статья, не стесняйтесь хлопать в ладоши. Это быстро, просто и бесплатно! Если у вас есть вопросы или полезные советы, оставьте их в комментариях ниже.

Чтобы читать больше моих колонок, вы можете подписаться на меня в LinkedIn и Twitter или проверить мое портфолио на CharlesStover.com.