Используется в связке с
react-router@5
В
react-router@>=6
появилисьclientLoader/loader
для загрузки данных
HOC для загрузки данных на страницу
Стразу же укажу альтернативы, хотя это решение использовалось в боевом проекте (сейчас его судьба мне не известна, проект был запущен мной в 2021 году), но это приложение имеет свои особенности которые и подтолкнули меня к созданию этого решения
Хотел получить механизм единой загрузки данных, чтобы избавиться от необходимости if/else
с лоудером
Пример:
const Page = () => { const {profile, isLoadingProfile} = useProfile(); const {todoList, isLoadingToDoList} = useToDoList(); if (isLoadingProfile) { return <div>Loading...</div>; } if (isLoadingToDoList) { return <div>Loading...</div>; } return ( <div> <div>{profile.name}</div> <ul> {todoList.map((todo) => ( <li>{todo.title}</li> ))} </ul> </div> ) }
На момент 2020-2021 годов ещё не было React Router v6, а о существовании swr
и @tanstack/react-query
я не знал. Судя по npmjs.com они только появлялись и набирали популярность. Мне понравился подход Next.js с загрузкой данных через функцию getInitialProps
(сейчас так уже не делают), который я и решил повторить
В итоге получился вот такой подход
// pages/TodoList.tsx const TodoList = ({ profile, todoList }) => ( <div> <div>{profile.name}</div> <ul> {todoList.map((todo) => ( <li>{todo.title}</li> ))} </ul> </div> ) export async function getInitialProps() { const profileResponse = await fetch("https://.../profile"); const todoListResponse = await fetch("https://.../todolist"); return { props: { profile: await profileResponse.json(), todoList: await todoListResponse.json() } }; } export default Page; // pages/index.tsx const TodoList = lazyPage(() => import("./TodoList")); const App = () => ( <Suspense fallback={<div>Loading...</div>}> <TodoList /> </Suspense> )