Skip to content

Новый убийца модальных окон для React прибыл

Управление модальными окнами и диалогами в React часто приводит к запутанному беспорядку из пропсов и состояний. Маленькая утилита под названием `react-call` полностью меняет правила игры, позволяя вызывать компоненты как простые асинхронные функции.

Theo Brandt
Hero image for: Новый убийца модальных окон для React прибыл

Кратко / Главное

Управление модальными окнами и диалогами в React часто приводит к запутанному беспорядку из пропсов и состояний. Маленькая утилита под названием `react-call` полностью меняет правила игры, позволяя вызывать компоненты как простые асинхронные функции.

Спагетти-код, который мы все пишем

Управление интерактивным пользовательским интерфейсом в React быстро превращается в запутанный беспорядок. Разработчики регулярно протаскивают пропсы (`prop drill`) общие состояния `isOpen` и обработчики `onClose` глубоко в дерево компонентов, передавая их через слои несвязанных компонентов. Это вынуждает родительские компоненты управлять видимостью дочернего пользовательского интерфейса, даже когда это не является их прямой задачей, что скрывает намерения и усложняет повторное использование компонентов в приложении.

Этот распространенный шаблон тесно связывает состояние пользовательского интерфейса с основной бизнес-логикой, рассеивая управление по многочисленным файлам. Результатом является классический спагетти-код, где простое модальное окно подтверждения или многошаговый мастер форм становится сетью взаимосвязанных вызовов `useState` и хуков `useEffect`. Такую тесно связанную логику трудно отслеживать, отлаживать и рефакторить, превращая незначительные корректировки пользовательского интерфейса в значительные усилия по разработке.

Традиционные решения, такие как Context API или React Portals, лишь частично облегчают эти проблемы. `Context` требует многословных провайдеров и потребителей, добавляя значительный бойлерплейт; `Portals` изолируют элементы DOM, но не предоставляют встроенного решения для управления состоянием или потоком управления. Важно отметить, что ни одно из них принципиально не решает основную архитектурную задачу: вызов компонента пользовательского интерфейса как асинхронной функции, которая возвращает прямое, действенное значение, вынуждая разработчиков использовать несвязанные, сильно зависящие от колбэков подходы.

Вызывайте компоненты как асинхронные функции

`react-call` переосмысливает управление интерактивным пользовательским интерфейсом. Он имитирует нативный API браузера `window.confirm`, позволяя компонентам приостанавливать выполнение, привнося интуитивно понятную, блокирующую модель непосредственно в современный React.

Вызывайте компоненты как асинхронные функции: `await Confirm.call()`. Выполнение приостанавливается, ожидая ввода пользователя — например, нажатия кнопки OK или Cancel — перед возобновлением. Это сохраняет бизнес-логику линейной и локальной для вызывающего компонента, упрощая сложные рабочие процессы.

Архитектура кардинально меняется. Устраните переменные состояния `isModalOpen`, избавившись от протаскивания пропсов. Откажитесь от колбэков `onClose` или `onSubmit`. Больше не требуются сложные провайдеры контекста или порталы для интерактивных элементов пользовательского интерфейса.

Вызываемый компонент, обернутый с помощью `createCallable`, действует как собственная точка монтирования. Разместите его как корневой тег в любом видимом месте; он будет работать как слушатель. `react-call` управляет несколькими активными экземплярами через внутренний стек, обрабатывая рендеринг и анимации выхода.

Под капотом `react-call` абстрагирует управление промисами и обрабатывает типизированные запросы/ответы из коробки. Эта легковесная утилита занимает менее 500Б и не имеет зависимостей. Полная поддержка горячей замены модулей (hot module replacement) поддерживает быстрые циклы разработки.

Внутри архитектуры `react-call`

Единый компонент Root формирует основу `react-call`, выступая в качестве собственной точки монтирования. Разместите этот вызываемый компонент как корневой тег в любом видимом месте вашего приложения, например, в `App.js`, где он будет работать как пассивный слушатель. Когда срабатывает несколько вызовов, `react-call` управляет ими через внутренний стек, обрабатывая рендеринг, чистые анимации выхода и автоматически обеспечивая изоляцию экземпляров.

Upsert предоставляет критически важный шаблон для одиночных элементов пользовательского интерфейса, таких как глобальные уведомления-тосты или оверлеи загрузки. В то время как `call()` создает новые экземпляры, `upsert()` предотвращает дублирование для компонентов, где должен быть активен только один экземпляр. Если экземпляр находится на экране, `upsert` плавно обновляет существующий компонент новыми данными на лету, избегая избыточного UI и обеспечивая контролируемый рендеринг единственного экземпляра.

Подключите UI напрямую к бэкенд-действиям, используя концепцию Mutation Flow и его хук `useMutationFlow`. Этот хук автоматически управляет состояниями ожидания, гарантируя, что ваш вызываемый UI, такой как модальное окно подтверждения, остается открытым с индикатором загрузки, пока выполняется асинхронная функция. Вызов разрешается и закрывается только после успешного завершения базового промиса, эффективно связывая состояние UI и мутации данных. Этот явный контроль, включая ручной `call.end()`, позволяет реализовать надежную обработку ошибок и механизмы повторных попыток без потери пользовательского контекста. Изучите более продвинутые шаблоны на react-call.

Практическая выгода

Разверните `react-call` быстро. Его размер минимален: <500B с нулевыми зависимостями, что обеспечивает незначительное влияние на размер бандла. Оберните любой компонент React с помощью компонента высшего порядка `createCallable`, чтобы мгновенно превратить его в ожидаемый примитив UI, готовый к прямому вызову.

Выйдите за рамки простых подтверждений. `react-call` отлично справляется с оркестровкой сложных интерактивных потоков. Реализуйте: - Многошаговые мастера - Динамические селекторы элементов - Асинхронные отправки форм с интегрированными состояниями загрузки

Используйте хук `useMutationFlow`, чтобы бесшовно привязать вызываемый UI к бэкенд-действиям, управляя состояниями ожидания и гарантируя, что UI остается активным до разрешения промисов.

Это не просто еще одна библиотека модальных окон. `react-call` представляет собой фундаментальный сдвиг в том, как вы управляете взаимодействием компонентов. Он устраняет избыточный код, связанный с состоянием, очищает ваш фронтенд-инструментарий и обеспечивает более чистую, читаемую архитектуру. Примите смену парадигмы; переосмыслите свой UI.

Часто задаваемые вопросы

Что такое react-call?

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

Чем `react-call` отличается от использования React Context для модальных окон?

`react-call` устраняет необходимость в глобальном провайдере контекста для управления состоянием модальных окон. Он локализует бизнес-логику в вызывающем компоненте, избегая проброса пропсов и сложного управления состоянием.

Для чего нужна функция 'Upsert' в `react-call`?

Upsert предназначен для одиночных UI-паттернов, таких как тосты или индикаторы загрузки. Он обновляет существующий экземпляр компонента новыми данными вместо создания нового, гарантируя, что на экране одновременно находится только один.

Подходит ли `react-call` для серверного рендеринга (SSR)?

Компоненты `createCallable` и `Root` поддерживают SSR. Однако сам метод `call()` является клиентским, так как он зависит от взаимодействия пользователя в браузере.

Found this useful? Share it.

One short daily email of tools worth shipping. No drip funnel.

one email a day · unsubscribe in two clicks · no third-party tracking

🚀Узнать больше

Будьте в курсе трендов ИИ

Откройте лучшие инструменты ИИ, агенты и MCP-серверы от Stork.AI.

P.S. Сделали что-то полезное? Опубликуйте на Stork