首先明确一个核心观点:HTMX 并非要取代 React,而是一种轻量化的前端增强层。借助几个简洁的 HTML 属性,浏览器便能自动发起请求并替换局部 DOM。在数据网格(Data Grid)这类需要频繁局部更新的场景下,HTMX 尤其得心应手。
React 在构建动态交互界面方面功能强大,但随着应用规模扩大,客户端渲染开销、包体积以及状态管理复杂度都会显著增加。HTMX 则提供了一条不同的路径:将部分更新逻辑交还给服务端处理,通过直接返回 HTML 片段在客户端替换相应区域。对于仪表盘、CRUD 页面以及需要高频刷新单元格的场景,HTMX 堪称给 React 减负的“第二引擎”。
本文将演示如何在 Next.js(基于 React 19)项目中集成 HTMX,并结合 Syncfusion React Data Grid,利用单条 SSE(Server-Sent Events)连接实现实时数据更新。

HTMX 为何适合与 React 及 Next.js 搭配使用
HTMX 提供的 hx-get、hx-swap、hx-trigger 等属性,允许浏览器在特定事件触发时自动发出请求并精确定位替换 DOM。对于数据网格这类需要频繁、局部更新的场景,由服务端直接返回 HTML 片段,远比在客户端维护大量同步状态更为直接高效。
例如,在仪表盘或 CRUD 页面中,部分单元格需要高频刷新。如果完全依赖客户端状态驱动,复杂度和性能开销会迅速膨胀;而 HTMX 正是擅长应对这种“局部、频繁、小改动”的更新模式。
在 Next.js(基于 React 19)项目中集成 HTMX
前置条件
- Node.js 20
- npm / pnpm / yarn
- Next.js 15.1
- React / React-DOM 19
- 任意编辑器(如 VS Code)
第 1 步:创建 Next.js 项目
代码语言:ja vascript
npx create-next-app@latest my-htmx-app --typescript --app
cd my-htmx-app && npm install
第 2 步:在 Layout 中加载 HTMX
HTMX 需要在页面生命周期的早期加载。建议将其直接置于 app/layout.tsx 中,以确保所有 hx-* 属性立即可用,并同时启用 SSE 扩展。
代码语言:ja vascript
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
这样做的理由是:Next.js 能够灵活控制脚本的加载顺序,无需额外的打包或构建配置,HTMX 在服务端渲染(SSR)和客户端渲染(CSR)生成的 DOM 上均能完美生效。
第 3 步:安装并配置 Syncfusion React 组件
代码语言:ja vascript
npm install @syncfusion/ej2-react-grids @syncfusion/ej2-react-buttons
然后在全局样式里引入 Tailwind 主题:
代码语言:ja vascript
@import "@syncfusion/ej2-react-grids/styles/tailwind.css";
@import "@syncfusion/ej2-react-buttons/styles/tailwind.css";
在 React Data Grid 中实现实时更新
本文将使用一个简单的订单列表进行演示:列包含 OrderID、CustomerID、Freight,其中 Freight 字段每 5 秒更新一次,以模拟实时价格波动。
常见误区:每行一个 SSE 连接
直观上,您可能会让每一行单独建立一条 SSE 连接来接收更新。然而,浏览器对并发 SSE 连接的数量设有硬性上限。正如作者所指出的:“前几行可以正常工作,但后续行就会失败。”
解决方案:一个 SSE 端点广播所有行
核心思路是:仅建立一条 SSE 连接,服务端每次推送时为每一行发送一个具名事件,例如 freight-updated-1001。每个单元格仅监听属于自身的事件名。这样一来,既能绕开浏览器连接数限制,又能实现精确的“行级别、单元格级别”更新。
创建 Data Grid(React + HTMX)
代码语言:ja vascript
import { useEffect } from "react";
import { GridComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-grids";
declare global { interface Window { htmx?: any; } }
const data = Array.from({ length: 10 }, (_, i) => ({
OrderID: 1000 + i + 1,
CustomerID: ["ALFKI", "ANANTR", "ANTON", "BLONP", "BOLID"][Math.floor(Math.random() * 5)],
OrderDate: new Date(Date.now() - i * 24 * 60 * 60 * 1000).toISOString(),
Freight: (2.1 * (i + 1)).toFixed(2),
}));
export default function Home() {
useEffect(() => {
if (typeof window === "undefined" || !window.htmx) { console.error("HTMX not loaded"); return; }
const container = document.querySelector("#htmx-container");
if (container) { window.htmx.process(container); }
const observer = new MutationObserver(() => { if (container) window.htmx.process(container); });
observer.observe(container || document.body, { childList: true, subtree: true });
return () => observer.disconnect();
}, []);
return (
(
{props.Freight}
)}
/>
);
}
这里的关键在于 data-hx-sse 属性:它负责连接 SSE 并监听对应事件,随后将事件数据替换到当前单元格中。
创建 SSE 端点
服务端通过一个静态 API 路由持续输出 text/event-stream 数据流:
代码语言:ja vascript
import { NextResponse } from "next/server";
export async function GET(request: Request) {
const headers = {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
};
const stream = new ReadableStream({
async start(controller) {
const interval = setInterval(() => {
for (let i = 1001; i <= 1010; i++) {
const newFreight = (Math.random() * 100).toFixed(2);
const payload = `event: freight-updated-${i}\ndata: ${newFreight}\n\n`;
controller.enqueue(new TextEncoder().encode(payload));
}
}, 5000);
request.signal.addEventListener("abort", () => {
clearInterval(interval);
controller.close();
});
},
});
return new NextResponse(stream, { headers });
}
这样,单条 SSE 连接便可将 10 行(甚至更多)的 Freight 更新广播出去,每个单元格仅消费自身感兴趣的事件。
最终效果如下:

GitHub 参考
示例代码仓库:github.com/SyncfusionExamples/htmx-nextjs-grid
常见问题
为什么要把 HTMX 和 React 混用?
作者的观点十分明确:HTMX 负责实现“快速、轻量、局部”的 HTML 替换——如表单提交、惰性加载区块、局部刷新、实时更新等;而 React 负责处理复杂、状态密集的 UI 部分。两者组合带来的优势包括:更小的包体积、更快的首屏加载速度、更少的前端状态以及更少的胶水代码。
什么时候选择 React + HTMX,而不是全靠 React/Next.js?
这种组合适用于以下场景:您希望将 JavaScript 负载降至更低,多数交互可通过服务端驱动的局部更新来实现,且后端本就能产出高质量的 HTML,此时“速度与简洁”比“复杂的客户端状态管理”更为重要。
结语
将 HTMX 与 Next.js / React Data Grid 结合使用,您可以同时获得 React 的组件化能力与 HTMX 的轻量级局部更新能力。在需要实时更新但又不想引入额外复杂状态层的数据网格场景中,这无疑是一条非常值得尝试的技术路线。
