С выпуском Hooks API в React появляются новые возможности для устранения еще большего количества шаблонов. Я хочу поговорить о Suspense.

Если вы этого не знаете, загляните на официальную страницу. Если коротко описать это, это компонент, как и любой другой, который принимает два свойства:

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

Вариант использования, о котором пишет большинство людей, включает синтаксис import(...). Но я здесь не об этом. Я утверждаю, что в большинстве случаев вам следует использовать Suspense вместо useEffect.

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

Проблема, которую я вижу в этом коде, может быть описана как скрытая зависимость. Вам нужен getUsernamecall для работы, но, в конце концов, вы застряли, если этого не произошло. Вы также делаете этот компонент невозможным для тестирования и повторного использования где-либо еще. Вызов getUsername нельзя имитировать или заменить, сервер должен существовать.

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

Простое изменение - сделать зависимость явной.

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

Но у нас все еще есть проблема. Наша опора - это Promise, а не просто данные. Это означает, что наш компонент по-прежнему должен ждать выполнения обещания, отображая загрузчик, пока он не выполняется.

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

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

Конечно, вся эта логика никуда не делась. Вот вызов последней версии нашего компонента, где User - наш компонент.

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

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

С помощью этой очень простой оболочки, назовем ее Lazy, вот вызов нашего нового User компонента.

На данный момент у нас есть унифицированный способ получения данных для одного компонента для рендеринга. Но тогда нужно ли нам копировать / вставлять этот фрагмент кода во все наши проекты? А как насчет мультипликаторов? А передавать Component внутри обратного вызова некрасиво, не так ли?

На все эти вопросы я бы сказал: вы еще помните название этой статьи? Да, пора ввести Suspense. Вот наш предыдущий компонент, но он заменяет наш собственный Lazy мощью, которую предлагает нам React.

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

И последнее, но не менее важное: как мы поддерживаем несколько асинхронных параметров? Может ли он работать с асинхронными компонентами (используя синтаксис imports(...))? Что насчет обоих?

Мы могли определенно рассмотреть все эти случаи. Если вы попытаетесь, то заметите, что вещи быстро становятся трудночитаемыми. Чтобы этого избежать, позвольте мне представить мою библиотеку Lazy-Props на примере:

Заключение

Мы еще раз заметили важность разделения выборки и отображения данных, чтобы иметь тестируемые и поддерживаемые компоненты. Одним из решений было бы написать нашу собственную оболочку для обработки выборки данных, но теперь React предоставьте нам одну: Suspense. Чтобы упростить его использование в сложных случаях, вы можете объединить его с библиотекой Lazy-Props, но, в конце концов, Suspense - это все, что вам нужно.