Глобальные индикаторы загрузки позволяют визуально сигнализировать пользователю о том, что выполняется асинхронная операция или происходит навигация между маршрутами. В TanStack Router это реализуется через встроенные механизмы отслеживания состояния маршрутов и их загрузок, что делает управление состоянием загрузки максимально декларативным и гибким.
Каждый маршрут в TanStack Router может иметь асинхронные загрузочные
функции, такие как loader или action. Эти
функции возвращают промисы, выполнение которых можно отслеживать для
отображения индикаторов загрузки. Ключевой элемент — свойство
pending маршрута. Оно отражает, выполняется ли в данный
момент асинхронная операция:
import { useRouter, RouterProvider } from '@tanstack/router'
function App() {
const router = useRouter()
return (
<>
{router.isPending && <div className="global-loader">Загрузка...</div>}
<RouterProvider router={router} />
</>
)
}
Пояснение:
router.isPending автоматически отслеживает все активные
асинхронные операции на маршрутах.pending на уровне маршрутовПомимо глобального состояния, TanStack Router позволяет отслеживать
загрузку конкретного маршрута через useMatch:
import { useMatch } from '@tanstack/router'
function RouteComponent() {
const match = useMatch('/profile')
return (
<>
{match.pending ? <Spinner /> : <Profile />}
</>
)
}
Особенности:
match.pending активен только для данного маршрута.TanStack Router поддерживает загрузку данных через
loader функции, которые возвращают промисы:
const profileRoute = {
path: '/profile',
loader: async () => {
const response = await fetch('/api/profile')
if (!response.ok) throw new Error('Ошибка загрузки')
return response.json()
}
}
Состояние pending автоматически учитывает выполнение
этих промисов. Для более детального контроля можно использовать
router.transition:
const router = useRouter()
useEffect(() => {
const unsub = router.transition.subscribe(transition => {
if (transition.status === 'pending') setLoading(true)
else setLoading(false)
})
return unsub
}, [router])
Ключевые моменты:
router.transition позволяет отслеживать
любую навигацию и асинхронные операции.TanStack Router интегрируется с React Suspense, что
позволяет декларативно показывать индикаторы загрузки при рендеринге
асинхронных данных:
import { Suspense } from 'react'
<Suspense fallback={<div>Загрузка данных...</div>}>
<Profile />
</Suspense>
Преимущества:
loader и компонентами,
использующими React.lazy.Для UX рекомендуется отображать глобальный индикатор только при длительных загрузках, чтобы не создавать мерцание интерфейса. Типичные подходы:
const [showLoader, setShowLoader] = useState(false)
useEffect(() => {
if (router.isPending) {
const timer = setTimeout(() => setShowLoader(true), 200)
return () => clearTimeout(timer)
} else {
setShowLoader(false)
}
}, [router.isPending])
.global-loader {
height: 4px;
width: 0%;
background-color: #007aff;
transition: width 0.3s ease;
}
.global-loader.active {
width: 100%;
}
В крупных приложениях может быть несколько одновременно активных
маршрутов. TanStack Router учитывает состояние всех асинхронных операций
и объединяет их в единый isPending флаг. Это позволяет:
Глобальные индикаторы загрузки в TanStack Router обеспечивают
простое, но мощное управление асинхронными состояниями приложения.
Использование isPending, match.pending,
подписок на transition и интеграция с Suspense
позволяет строить интерфейсы с плавной навигацией и визуальной обратной
связью для пользователя.