停止流式纯文本:使用 React Server Components 解锁交互式 UI
I’m happy to help translate the article, but I need the actual text you’d like translated. Could you please paste the content of the article (excluding the source link you’ve already provided) here? Once I have the text, I’ll translate it into Simplified Chinese while preserving the original formatting, markdown, and technical terms.
演进:从新闻滚动条到实时广播
旧方式(仅文本)
想象一个实时新闻滚动条。信息不断流动,但它是静态的。客户端是被动的接受者。
如果用户请求,“给我展示 Q3 销售额的图表”,AI 会流回描述图表的文本,或许是一个 JSON 对象。用户必须等流结束后 UI 才能渲染。
新方式(流式 UI)
现在,想象一个实时广播,记者可以动态地在信息流中插入交互式仪表盘、图表和表单。这就是
streamable‑ui模式。
与其发送{"chart":"data…"},服务器发送的是序列化的 React 组件:
// Example placeholder – the actual component is streamed from the server
客户端接收后立即进行 hydrate,用户可以在 AI 仍在生成其余响应时进行悬停、缩放和点击。
架构:RSC 与服务器操作
它是如何在底层工作的?它依赖于两个支柱:
- React Server Components (RSCs) – 服务器渲染组件树并将其序列化为特殊负载(使用 React 的 Flight 协议)。该负载通过 SSE(服务器发送事件)进行流式传输。
- Server Actions – 流式传输的组件不仅仅是静态 HTML。它们可以包含交互元素(按钮、表单),这些元素会通过 Server Actions 触发服务器上的安全函数。
这形成了一个双向流:
| 方向 | 描述 |
|---|---|
| Server → Client | 流式传输 UI 组件。 |
| Client → Server | 用户点击该组件内的按钮。 |
| Server → Client | Server Action 执行,可能触发更多 AI 生成并流式传输新组件。 |
“实时购物车”类比
想象一下直播主在卖产品。
| 模式 | 体验 |
|---|---|
| 仅文字 | 主播描述商品。你在聊天中输入提问。 |
| 流媒体 UI | 主播在视频画面上直接叠加一个 “加入购物车” 按钮和尺码选择器。你可以 立即 点击,而无需暂停视频。 |
这就是我们正在构建的体验。
代码示例:流式 AI 仪表盘
我们将构建一个 SaaS 功能,让 AI 生成摘要报告并以交互式 React 组件的形式流式传输。
1️⃣ 服务端实现
文件: app/api/generate-report/route.ts
// app/api/generate-report/route.ts
import { streamUI } from 'ai/rsc';
import { OpenAI } from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY || '',
});
// The component to be streamed
const ReportComponent = ({ data }: { data: string }) => {
return (
<div>
<h3>AI Generated Report</h3>
<p>{data}</p>
<button
onClick={() => alert('Report acknowledged!')}
className="mt-3 px-3 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700"
>
Acknowledge
</button>
</div>
);
};
export async function POST(req: Request) {
const { prompt } = await req.json();
const result = await streamUI({
model: 'gpt-4-turbo-preview',
system: 'You are a helpful assistant that generates concise reports.',
prompt: `Generate a summary report for: ${prompt}`,
// The Magic Mapping:
// When the AI generates text, we wrap it in our React Component
text: ({ content }) => {
return <ReportComponent data={content} />;
},
initial: 'Generating report...',
});
return result.toAIStreamResponse();
}
2️⃣ 客户端实现
文件: app/page.tsx
// app/page.tsx
'use client';
import { useCompletion } from 'ai/react';
export default function DashboardPage() {
const {
completion,
input,
handleInputChange,
handleSubmit,
isLoading,
} = useCompletion({
api: '/api/generate-report',
});
return (
<div>
<h2>SaaS Dashboard</h2>
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={handleInputChange}
placeholder="Enter prompt"
/>
<button type="submit" disabled={isLoading}>
Generate
</button>
</form>
<h3>Output:</h3>
{/* The SDK handles the deserialization of the RSC payload */}
{completion ? (
// The payload is already a React element, so we can render it directly.
<>{completion}</>
) : (
<p>No report generated yet.</p>
)}
</div>
);
}
注意:
useCompletion返回的completion是一个 React 元素(或元素树),SDK 会从流式 RSC 负载中重建它。无需使用dangerouslySetInnerHTML。
回顾
- Streaming UI 让服务器在 AI 仍在生成 时向客户端推送交互式 React 组件。
- React Server Components + Server Actions 为我们提供安全、双向、实时的 UI 管道。
- 该模式可与 Vercel AI SDK(服务器端
streamUI,客户端useCompletion)配合使用,并可适配任何基于 LLM 的工作流。
现在你可以超越静态文本,构建真正 实时 的 AI 增强体验! 🚀
{isLoading && (
<div>
● Streaming component...
</div>
)}
全屏控制
Enter fullscreen mode
Exit fullscreen mode
Source: …
高级模式:LangGraph 与最大迭代策略
当你将流式 UI 与 AI 代理结合时,会进入一个循环工作流:
- AI 生成 UI。
- 用户与之交互。
- 该交互反馈给 AI,以生成 下一步。
这非常强大,但也很危险。没有防护措施,AI 可能会陷入无限生成组件的循环。
解决方案:最大迭代策略
使用 LangGraph,我们可以将 AI 逻辑结构化为有状态的图。
添加一个条件边(即“策略”),检查迭代计数。如果计数超过限制(例如 5 步),图会强制转向 END 节点,优雅地终止流程。
这可确保即使 AI 逻辑出现混乱,你的应用仍保持稳定。
常见陷阱需避免
- 幻觉 JSON – 不要让 LLM 生成 React 组件结构(JSON/JSX),它会失败。相反,让它生成 内容,并在服务器上将该内容映射到预定义的组件(如代码示例所示)。
- Vercel 超时 – 无服务器函数有超时限制(10 秒–15 秒)。如果你的 AI 生成较慢,流可能会被截断。始终使用
streamUI(它能高效保持连接活跃)并优化提示词。 - 水合错误 – 服务器组件无法访问浏览器 API(
window、document)。如果需要客户端交互(如示例中的onClick),确保事件处理逻辑由客户端水合过程处理,或包装在客户端组件中。
结论
流式传输 React 组件让我们从 “Generative Text” 进入 “Generative UI”。
它将用户体验从被动的阅读‑等待循环转变为主动的、迭代的协作。通过利用 Vercel AI SDK 和 React Server Components,你可以构建感觉瞬时且深度交互的应用。AI 不仅告诉你该怎么做;它在你眼前为你构建完成任务的工具。
这里展示的概念和代码直接取自书籍 The Modern Stack: Building Generative UI with Next.js, Vercel AI SDK, and React Server Components ——Amazon Link —— 属于 AI with JavaScript & TypeScript Series(Amazon Link)。
另外,请查看 Leanpub 上的所有其他编程电子书。