"use client"; // 不自动运行 // 客户端组件:有状态和事件处理。读取路由处理器返回的流,逐段显示。 import { useRef, useState } from "react"; export function Chat() { const [answer, setAnswer] = useState(""); const [busy, setBusy] = useState(false); const ctrl = useRef(null); async function ask(formData: FormData) { ctrl.current?.abort(); ctrl.current = new AbortController(); setAnswer(""); setBusy(true); try { const resp = await fetch("/api/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ question: formData.get("q") }), signal: ctrl.current.signal, }); if (!resp.body) throw new Error("没有响应体"); const reader = resp.body.pipeThrough(new TextDecoderStream()).getReader(); for (;;) { const { value, done } = await reader.read(); if (done) break; setAnswer((a) => a + value); } } catch (e) { if ((e as Error).name !== "AbortError") setAnswer("出错了,请重试"); } finally { setBusy(false); } } return (
{busy && }

{answer}

); }