В Solid.js есть механизм для асинхронной загрузки данных, который
значительно упрощает работу с компонентами, зависящими от внешних
источников данных, таких как API или базы данных. Одним из ключевых
инструментов для этого является компонент SuspenseList,
который предоставляет более гибкую координацию загрузки нескольких
асинхронных данных и упрощает процесс их рендеринга.
Компонент SuspenseList был разработан для улучшения
взаимодействия с асинхронным рендерингом, позволяя координировать и
управлять порядком загрузки нескольких асинхронных операций. В Solid.js
асинхронный рендеринг базируется на Suspense, который
работает аналогично похожему механизму в React. Однако Solid.js внедряет
несколько уникальных концепций, что позволяет значительно повысить
производительность и упростить процесс работы с асинхронностью.
Компонент SuspenseList служит для того, чтобы
координировать множество асинхронных операций в определённом порядке.
Это особенно полезно, когда есть необходимость сначала загрузить
несколько компонентов, а затем рендерить их все одновременно, чтобы
избежать “моргающего” интерфейса или фрагментированных обновлений.
Это свойство определяет порядок, в котором дочерние компоненты должны быть показаны после того, как все они загрузятся. Оно может принимать несколько значений:
Пример:
<SuspenseList revealOrder="forwards">
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent1 />
</Suspense>
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent2 />
</Suspense>
</SuspenseList>
В этом примере, если AsyncComponent1 загружается
быстрее, чем AsyncComponent2, то он будет отрендерен
первым, если указан порядок “forwards”.
С помощью этого свойства можно указать поведение “хвоста” списка, который будет показан, если часть дочерних компонентов всё ещё не загружена. Это помогает предотвратить пустые или невалидные состояния интерфейса, когда одни компоненты загружены, а другие — нет.
<SuspenseList tail="collapsed">
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent1 />
</Suspense>
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent2 />
</Suspense>
</SuspenseList>
Если установлен параметр tail="collapsed", то дочерние
компоненты, которые ещё не загрузились, не будут занимать место в DOM,
что исключает проблемы с макетом и делает интерфейс более
аккуратным.
Для того чтобы лучше понять, как работает SuspenseList,
рассмотрим пример с загрузкой данных для нескольких компонентов, каждый
из которых делает асинхронный запрос к серверу. В реальной разработке
часто нужно отобразить данные из нескольких источников, и каждый запрос
может занять разное количество времени.
Пример:
import { createResource, Suspense, SuspenseList } from "solid-js";
function fetchData1() {
return new Promise(resolve => setTimeout(() => resolve("Data 1 loaded"), 3000));
}
function fetchData2() {
return new Promise(resolve => setTimeout(() => resolve("Data 2 loaded"), 2000));
}
function Component1() {
const [data] = createResource(fetchData1);
return <div>{data()}</div>;
}
function Component2() {
const [data] = createResource(fetchData2);
return <div>{data()}</div>;
}
function App() {
return (
<SuspenseList revealOrder="forwards">
<Suspense fallback={<div>Loading...</div>}>
<Component1 />
</Suspense>
<Suspense fallback={<div>Loading...</div>}>
<Component2 />
</Suspense>
</SuspenseList>
);
}
В данном примере, компонент Component1 будет
показываться первым, несмотря на то, что его загрузка может занять
больше времени, чем у Component2, если они загружаются
асинхронно. Все это происходит благодаря свойству
revealOrder="forwards", которое контролирует порядок
рендеринга.
Предсказуемость и контроль: При использовании
SuspenseList разработчик может точно контролировать, в
каком порядке и когда компоненты должны быть отображены. Это даёт больше
гибкости и позволяет избегать неудобных ситуаций с “моргающими”
компонентами.
Управление асинхронностью: Вместо того чтобы вручную отслеживать, когда данные загружены и обновлять состояние, Solid.js использует механизмы Suspense и SuspenseList, что значительно упрощает асинхронную работу с компонентами.
Гибкость интерфейса: Возможность настраивать
порядок загрузки компонентов и использовать параметры, такие как
tail, позволяет создавать более плавные и отзывчивые
интерфейсы, минимизируя “прыгающие” элементы.
Упрощение кода: Механизм асинхронного рендеринга, встроенный в Solid.js, позволяет разработчику сосредоточиться на логике приложения, а не на управлении состоянием загрузки. Все заботы о загрузке данных и их рендеринге берет на себя фреймворк.
В отличие от традиционных методов управления асинхронной загрузкой в
других фреймворках, где необходимо вручную управлять состояниями
загрузки, успехов и ошибок, Solid.js автоматически управляет состоянием
компонента. В этом контексте использование Suspense и
SuspenseList делает разработку более прозрачной и
интуитивно понятной. Если в React вы могли бы использовать
Suspense и React.lazy(), то в Solid.js это
выполняется намного быстрее и с меньшими затратами памяти, благодаря
использованию реактивности вместо виртуального DOM.
Использование компонента SuspenseList в Solid.js
позволяет легко координировать загрузку нескольких асинхронных операций
и компонентов, создавая более плавные и отзывчивые пользовательские
интерфейсы. Гибкость параметров, таких как revealOrder и
tail, предоставляет дополнительные возможности для
управления порядком рендеринга и минимизации пустых состояний
интерфейса. Благодаря этому инструменту разработчики могут существенно
упростить код, повысив его производительность и удобство.