Получение списка покемонов с использованием PokeAPI с Remix Framework
Несколько недель назад Документация ReactJS получила серьезное обновление. Эта новая документация улучшается с помощью таких примеров, как диаграммы, иллюстрации, задачи и более 600 новых интерактивных примеров. Это будет очень полезно для новичков в ReactJS и для опытных разработчиков ReactJS, которые хотят отточить свои глубокие знания о том, как работает React.
Хотя в новой документации есть много замечательных аспектов, я хотел бы сосредоточиться на одном: разделе Начало нового проекта React.
Существенным изменением в разделе Начало нового проекта React является то, что в официальной документации ReactJS больше не упоминается Create-React-App (CRA). Вместо этого они рекомендуют фреймворки React производственного уровня, такие как Next.js, Gatsby и Remix.
В их предыдущей унаследованной документации единственными рекомендуемыми фреймворками React были Next.js и Gatsby. Однако в новой документации они представили новый рекомендуемый фреймворк под названием Remix.
Я создам пример фрагмента кода в Remix и эквивалентный пример в Next.js. Поскольку Next.js уже довольно давно является частью экосистемы внешнего интерфейса, многие инженеры внешнего интерфейса будут лучше знакомы с его концепциями.
Что такое ремикс?
Remix — это полнофункциональная платформа React с вложенной маршрутизацией. Она позволяет разбить приложение на вложенные части, которые могут загружать данные параллельно и обновляться в ответ на действия пользователя.
Ключевые особенности ремикса
Я впервые попробовал Remix, чтобы создать простой список покемонов, который извлекает данные из PokeAPI. В этой статье я объясню несколько вещей о Remix и о том, что я узнал, используя его в первый раз.
Конечный результат этого проекта вы можете посмотреть по этой ссылке.
Загрузка данных
Одной из основных функций Remix является упрощение взаимодействия с сервером для передачи данных в компоненты. Это эквивалентно функции getServerSideProps
в Next.js.
Здесь я обрабатываю две функции для этого веб-сайта:
- Получение списка покемонов для первоначального рендера.
- Получение следующего покемона для разбиения на страницы.
export const loader = async ({ request }: LoaderArgs) => { // pagination handling const url = new URL(request.url); const query = url.searchParams.get("next"); if (query) { const fetchPoke = await fetch(query); const fetchPokeJson = await fetchPoke.json(); return json(fetchPokeJson); } // end of pagination handling // initial fetch const fetchPoke = await fetch("https://pokeapi.co/api/v2/pokemon"); const fetchPokeJson = await fetchPoke.json(); return json(fetchPokeJson); // end of initial fetch }; interface LoaderData { count: number; next: string; results: { name: string; url: string; }[]; } import { useLoaderData } from "@remix-run/react"; export default function PokeList() { // Obtain the data returned from the server using useLoaderData(). const pokeData = useLoaderData() as LoaderData; return ( <SimpleGrid cols={4} breakpoints={[ { maxWidth: "sm", cols: 2 }, { maxWidth: "md", cols: 3 }, { maxWidth: "lg", cols: 4 }, ]} > {poke.results.map((x, y) => { return ( <Card key={x.name}> <Card.Section> <Center> <Image withPlaceholder width={120} height={120} src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${y + 1 }.png`} alt={x.name} /> </Center> </Card.Section> <Text>{x.name}</Text> </Card> ); })} </SimpleGrid> ); }
В Next.js вы можете быть знакомы с похожей концепцией:
function Page({ data }) { // Render data... } // This gets called on every request export async function getServerSideProps() { // Fetch data from external API const res = await fetch(`https://.../data`) const data = await res.json() // Pass data to the page via props return { props: { data } } }
Маршрутизация
Remix также использует систему маршрутизации на основе файлов, аналогичную другим метафреймворкам в текущей экосистеме внешнего интерфейса. Однако внутренняя маршрутизация Remix построена поверх react-router-dom. Маршрутизация, возможно, самая важная концепция для понимания в Remix. Все начинается с ваших маршрутов: компилятор, первоначальный запрос и почти каждое последующее взаимодействие с пользователем.
Моя главная рекомендация при начале изучения Remix — сначала понять основные концепции того, как работает их маршрутизация, прежде чем углубляться в другие разделы. Однако, если вы имеете опыт работы с реактивным маршрутизатором, вы можете найти похожие концепции в маршрутизации Remix.
Вот пример структуры маршрутизации в Remix. Каждый новый файл, который вы создаете в папке маршрутов, будет доступен через URL-адрес страницы, поэтому важно понимать основные концепции маршрутизации Remix.
|--app |--routes |--$name.tsx -> https://example.com/* |--index.tsx -> https://example.com |--PokeList.tsx -> https://example.com/pokelist
Вот эквивалентная структура маршрутизации в Next.js:
|--pages |--index.tsx -> https://example.com |--PokeList.tsx -> https://example.com/pokelist |--[name] |--index.tsx -> https://example.com/*
Как вы можете видеть здесь, у нас есть два маршрута, которые можно объединить в один макет внутри одного URL-адреса; это называется Вложенная маршрутизация. Вложенная маршрутизация — это общая идея привязки сегментов URL к иерархии компонентов пользовательского интерфейса. В Remix вы обнаружите, что почти в каждом случае сегменты URL-адреса определяют:
- Макеты для отображения на странице
- Пакеты JavaScript с разделением кода для загрузки
- Зависимости данных этих макетов
Поскольку Pokelist — это маршрут, да, вы можете получить доступ к URL по этой ссылке.
В некоторых случаях прямой доступ к этим маршрутам может быть приемлемым, но в моем случае я запрещаю прямой доступ к URL-адресу, потому что эти маршруты вызовут ошибку. Загрузчик данных для получения списка покемонов находится в routes/index.tsx
.
/** * prevent direct access to the url */ export const loader = async () => { return redirect('/'); }; const PokeList = () => { ... ... }; export default PokeList;
Параметры рендеринга
Согласно Twitter thread от сопровождающего самого Remix, Remix в настоящее время поддерживает только рендеринг на стороне клиента (CSR) и рендеринг на стороне сервера (SSR) и не имеет таких функций, как генерация статического сайта (SSG). В результате он обычно ожидает, что у вас есть сервер.
Стиль
В современной экосистеме существуют десятки подходов и фреймворков для стилизации. Remix поддерживает многие из них «из коробки», но фреймворки, которые требуют прямой интеграции с компилятором Remix и ожидают, что Remix автоматически вставит стили на страницу, сейчас не работают.
Remix все еще исследует, как лучше всего поддерживать различные библиотеки стилей, не жертвуя при этом пользовательской сетевой вкладкой и не усложняя обслуживание Remix.
Вы должны быть осторожны при выборе системы дизайна для использования с Remix, так как некоторые функции вашей библиотеки системы дизайна могут не работать в Remix или наоборот.
Одним из примеров является библиотека Mantine; при использовании Mantine в Remix рендеринг сервера потоковой передачи не будет работать. Вот руководство для получения дополнительной информации.
Граница ошибки
В Remix вы можете получить доступ к встроенному API для обработки границ ошибок для каждого файла в подкаталогах папки маршрутов. Вы можете использовать это для обработки любых ошибок, связанных с вашими компонентами маршрута, включая обработку ошибок, выдаваемых вашим загрузчиком.
export const loader = async ({ params }: LoaderArgs) => { const fetchData = await fetch(`https://pokeapi.co/api/v2/pokemon/${params.name}`); if (fetchData.status !== 200) { throw new Error(); } const fetchJson = await fetchData.json(); return json(fetchJson); } // your error boundary export function ErrorBoundary({ error }) { // log your error yourLogger(error); return ( <Container> <Stack> <Alert color={'red'}> Error </Alert> </Stack> </Container> ); } const PokeDetail = () => { ... ... } export default PokeDetail;
Заключение
Remix — еще один метафреймворк, появившийся в экосистеме ReactJS. Теперь у нас есть три варианта, рекомендуемые документацией ReactJS: Next.js, Gatsby и Remix.
По моему личному мнению, после того, как я впервые попробовал Remix, я чувствую, что этот фреймворк имеет более высокую кривую обучения, чем Next.js.
Если ваш проект или компания в настоящее время создает собственную внутреннюю структуру с зависимостями от react-router-dom, вам следует проверить Remix, так как теперь документация ReactJS рекомендует его для создания нового приложения React.