Безболезненные и эффективные концепции управления состоянием React для приложений реального времени.

Обновление после публикации

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

Введение

Слушай, я ценю твое время. Вы заняты, и я это понимаю, так что давайте сразу перейдем к делу: это для тех из вас, кто ищет оптимальные стратегии управления состоянием для разработки приложений с интенсивным использованием данных в реальном времени. Мы будем использовать React и Socket.io. Это не пошаговое руководство, а скорее обзор реализации. Клонируйте репо, если хотите углубиться. Двигаясь дальше, я предполагаю, что читатель уже знаком с Shadow DOM, жизненным циклом рендеринга React, компонентами более высокого порядка (HOC), Context API и основами Socket.io. Если нет, прочтите и возвращайтесь!

Я также избавлюсь от этого пораньше: я не уверен, будет ли это по-прежнему противоречивым мнением в 2020 году, но я не поклонник структур государственного управления. Слишком много сложностей, на мой вкус. Не стесняйтесь не соглашаться со мной, но когда дело доходит до разработки сложных пользовательских интерфейсов с тысячами параметров, я остановился на стратегии, которая использует комбинацию провайдера верхнего уровня, использующего встроенный контекстный API React, чтобы заботиться о том, что я называют «макросами», расширенными простой системой публикации / подписки EventEmitter, чтобы заботиться о том, что я называю «микросистемами».

Я объясню.

Краткое описание пространств имен модулей

Зачем мне

import MyModule from '../foo/bar/baz/MyModule';

когда я могу просто

import { MyModule } from '../Modules'; ?

Имеет ли это смысл?

Другими словами, если все мои компоненты React находятся в папке components, я буду экспортировать их из components/index.js следующим образом:

export { Component1 } from './Component1';
export { Component2 } from './Component2';

Теперь, когда я пишу код для views/MyPage.js, мы можем просто

import { Component1, Component2 } from '../components' .

То же самое относится и к модулям CommonJS в моей серверной части Node.js.

Прохладный? Прохладный.

Макросы

Макросы - это часть общей картины. Данные, которые вы на самом деле хотите иметь глобальный доступ. Данные с более низкой скоростью оборота, чем постоянный натиск сообщений сокета, отправляемых клиенту. Например, аутентификация и тематизация - это фрагменты данных, которые попадают в эту категорию. Очевидно, ваш вариант использования может отличаться. В любом случае, мы хотели бы убедиться, что при изменении состояния на верхнем уровне нашего приложения мы не a) повторно отрисовываем каждый дочерний элемент в дереве компонентов, или b ) выполнение непристойного количества бурения опор только для того, чтобы получить данные там, где они необходимы.

Правило №1: Просмотры получают макросы.

Вверху это выглядит так:

Просто магазин, предоставляющий состояние нашим представлениям. Достаточно просто.

* Увеличение *

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

* Увеличение *

Это делает разметку для представлений относительно простой - просто обращайтесь к макросам через props и делайте с ними все, что хотите.

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

* Увеличение *

Функция подключения - это просто HOC, который разделяет представление между Потребителем контекста:

Но это не просто компонент Consumer встроенного Context API - он принимает данные, переданные ему от Provider, и прикрепляет их к свойствам каждого дочернего компонента:

Некоторые разработчики остановились бы на этом, заменили вызов издателя в Provider на setState (), и прекратили его. Я встану на колени и попрошу вас не управлять состоянием всего вашего приложения в одном магазине провайдера. Пожалуйста. Это не масштабируется. Вы будете заниматься бурением в течение нескольких дней, и ваше приложение будет работать медленнее, чем больше оно станет. Есть более эффективные способы передачи данных вашим компонентам. Просто выслушай меня.

Микро

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

Правило № 2: Компоненты подписываются на темы, чтобы получать микросхемы.

* Увеличение *

Вот внутренности этого компонента, возвращаемые представлением Home.js:

Это пара динамичных строк кода, а? Вкратце, это функция, которая принимает два аргумента: 1) компонент React и 2) тему. Он возвращает компонент React, который отслеживает события в указанной теме. В этом примере JSX отображает данные темы слева, а свойства, передаваемые нашим поставщиком, справа.

Вот результат:

Очевидно, здесь есть еще несколько HOC.

* Увеличение *

Как и connect (), функция subscribe () возвращает составной компонент. Этот компонент принимает свойство topic, которое сообщает ему, какое событие следует слушать.

* Увеличение *

Компонент «Подписчик» в некотором смысле является поставщиком собственного типа. Он прослушивает события, генерируемые в указанной теме, сохраняет их в своем локальном состоянии, повторно визуализируя дочерние элементы только тогда, когда он получает соответствующие данные. Он прикрепляет это состояние к дочернему компоненту вместе со всеми другими переданными ему реквизитами, так что на уровне представления разметка выглядит как обычный JSX. Здесь нечего смотреть…

* Смотрит налево *

И последнее, но не менее важное: небольшой API издателя, который объединяет все воедино:

Вывод

Вот и все! В этой статье мы взглянули на краткий обзор концепций управления состоянием React, которые предлагают нам гибкость и эффективность. Мы можем разделить наши проблемы на два типа данных и удобно отправлять соответствующие фрагменты информации непосредственно компонентам по мере необходимости, что приводит к высокооптимизированной визуализации. В этой настройке компоненты могут даже напрямую связываться друг с другом. Я считаю эту настройку идеальной для приложений с интенсивным использованием данных (и музыкальных).

Если вы нашли эту статью полезной, пришлите справку. Я стажер!

LinkedIn | Www.natalieb.me