Данные и обработчики маршрутов

Отдавайте развёртывания из app/api, загружайте их на странице и отправляйте новые.

Приложение этой главы работает в вашей консоли. Откройте её сочетанием ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (сначала включите функции разработчика), затем попробуйте приложение.
Смотреть главу3:32

В этой главе

  • Обработчик маршрута
  • Загрузка данных на странице
  • Состояния загрузки и ошибки
  • Потоковая передача

Acme Deploys нужны реальные данные. Обработчики маршрутов находятся рядом с вашими страницами в app/, используют веб-API Request и Response и работают при запуске text dev и text start. У них тот же origin, что и у приложения, поэтому запросам не нужна настройка CORS.

Обработчик маршрута

app/api/deployments/route.ts+10ts
Добавлено: import { DEPLOYMENTS, createDeployment } from "../../../lib/deployments";Добавлено: Добавлено: export function GET(): Response {Добавлено:   return Response.json(DEPLOYMENTS);Добавлено: }Добавлено: Добавлено: export async function POST(req: Request): Promise<Response> {Добавлено:   const deployment = createDeployment(await req.json());Добавлено:   return Response.json(deployment, { status: 201 });Добавлено: }

Вызовите его из командной строки консоли, пока работает text dev:

await (await fetch("/api/deployments")).json()

Загрузка данных на странице

Загружайте данные в эффекте и показывайте <Spinner>, пока они не придут. r повторно загружает данные; n отправляет запрос на новое развёртывание, которое отображается как собирающееся и переходит в состояние готовности после завершения сборки.

app/deployments/page.tsx+21-2tsx
Удалено: import { DEPLOYMENTS } from "../../lib/deployments";Добавлено: import { useEffect, useState } from "react";Добавлено: import { Spinner, useInput } from "@textjs/app";Добавлено: import type { Deployment } from "../../lib/deployments";export default function DeploymentsPage() {Добавлено:   const [rows, setRows] = useState<Deployment[]>([]);Добавлено:   const [loading, setLoading] = useState(true);Добавлено: Добавлено:   const refetch = async () => {Добавлено:     setLoading(true);Добавлено:     setRows(await (await fetch("/api/deployments")).json());Добавлено:     setLoading(false);Добавлено:   };Добавлено:   useEffect(() => void refetch(), []);Добавлено: Добавлено:   useInput((e) => {Добавлено:     if (e.input === "r") void refetch();Добавлено:     if (e.input === "n") void fetch("/api/deployments", { method: "POST", body: "{}" }).then(refetch);Добавлено:   });Добавлено: Добавлено:   if (loading) return <Spinner label="Loading deployments…" />;  return (    <Box className="flex-col">Удалено:       {DEPLOYMENTS.map((d) => (Добавлено:       {rows.map((d) => (        <Box key={d.id} className="flex-row h-1 gap-2">Добавлено:           <Status status={d.status} />          …

Состояния загрузки и ошибки

Вместо ручной обработки loading используйте loading.tsx рядом со страницей: он отображается, пока её рендеринг приостановлен, а error.tsx перехватывает все ошибки, которые она выбрасывает. Оба файла содержат обычные компоненты:

app/deployments/loading.tsxtsx
import { Spinner } from "@textjs/app";export default function Loading() {  return <Spinner label="Loading deployments…" />;}

Потоковая передача

Обработчики могут возвращать ReadableStream: так журналы сборки поступают на панель управления строка за строкой. О событиях server-sent events и проксировании локального демона читайте в разделе Обработчики маршрутов.

Попробовать

Это Acme Deploys в конце главы, работающее в DevTools. Нажмите на панель, затем используйте клавиши ниже.

▼ 06 · Данные и обработчики маршрутов

Открыть консоль

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

Приложение рендерится в DevTools.Сначала включите «Показывать функции для веб-разработчиков» в Safari: «Настройки» → «Дополнения». Затем щёлкните здесь и нажмите r.

Открыть на компьютере

Это приложение рендерится в консоли DevTools, для которой нужен браузер на компьютере.

Тест

2 вопроса

Ответьте на все вопросы, чтобы завершить главу.

Что возвращают обработчики маршрутов?

 

Какой файл отображается, пока маршрут приостановлен?