Данные и обработчики маршрутов
Отдавайте развёртывания из app/api, загружайте их на странице и отправляйте новые.
В этой главе
- Обработчик маршрута
- Загрузка данных на странице
- Состояния загрузки и ошибки
- Потоковая передача
Acme Deploys нужны реальные данные. Обработчики маршрутов находятся рядом с вашими страницами в app/, используют веб-API Request и Response и работают при запуске text dev и text start. У них тот же origin, что и у приложения, поэтому запросам не нужна настройка CORS.
Обработчик маршрута
Добавлено: 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 отправляет запрос на новое развёртывание, которое отображается как собирающееся и переходит в состояние готовности после завершения сборки.
Удалено: 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 перехватывает все ошибки, которые она выбрасывает. Оба файла содержат обычные компоненты:
import { Spinner } from "@textjs/app";export default function Loading() { return <Spinner label="Loading deployments…" />;}Потоковая передача
Обработчики могут возвращать ReadableStream: так журналы сборки поступают на панель управления строка за строкой. О событиях server-sent events и проксировании локального демона читайте в разделе Обработчики маршрутов.
Попробовать
Это Acme Deploys в конце главы, работающее в DevTools. Нажмите на панель, затем используйте клавиши ниже.
Открыть консоль
Приложение рендерится в DevTools.Сначала включите «Показывать функции для веб-разработчиков» в Safari: «Настройки» → «Дополнения». Затем щёлкните здесь и нажмите r.
Открыть на компьютере
Это приложение рендерится в консоли DevTools, для которой нужен браузер на компьютере.
Тест
2 вопросаОтветьте на все вопросы, чтобы завершить главу.