This commit is contained in:
2026-04-14 12:38:51 +08:00
parent bb7e654589
commit 53a4174aa9
4 changed files with 35 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
import { hydrateRoot } from 'react-dom/client'; import { hydrateRoot } from 'react-dom/client';
import App from './pages/a/main'; import App from './pages/a/ClientApp';
// import AServer from './pages/a/server/index.tsx'; // import AServer from './pages/a/server/index.tsx';
declare global { declare global {

17
src/pages/a/ClientApp.tsx Normal file
View File

@@ -0,0 +1,17 @@
'use client';
import List from './List.tsx';
// Client Component - 用于 hydration结构需要和 ServerApp 一致
declare global {
interface Window {
__SERVER_DATA__?: { version: string };
}
}
export default function ClientApp() {
const version = typeof window !== 'undefined' && window.__SERVER_DATA__?.version
? window.__SERVER_DATA__.version
: 'loading';
return <List version={version} />;
}

View File

@@ -1,18 +1,6 @@
import List from './List.tsx'; import List from './List.tsx';
// 模拟异步获取数据 // Server Component - 通过 props 接收数据,不再自己 fetch
async function fetchData() { export default async function ServerApp({ version }: { version: string }) {
await new Promise(resolve => setTimeout(resolve, 1000)); return <List version={version} />;
return { version: '2.0.0', timestamp: Date.now() };
}
// Server Component - 直接 await 获取数据
export default async function ServerApp() {
const data = await fetchData();
return (
<div>
<h2>Server Time: {new Date(data.timestamp).toLocaleTimeString()}</h2>
<List version={data.version} />
</div>
);
} }

View File

@@ -19,7 +19,13 @@ const mimeTypes: Record<string, string> = {
'.ico': 'image/x-icon', '.ico': 'image/x-icon',
}; };
async function ssrRender(res: http.ServerResponse, version: string) { // 模拟异步获取数据
async function fetchServerData() {
await new Promise(resolve => setTimeout(resolve, 1000));
return { version: '2.0.0', timestamp: Date.now() };
}
async function ssrRender(res: http.ServerResponse, routeVersion?: string) {
let template: string; let template: string;
try { try {
template = fs.readFileSync(indexHtmlPath, 'utf-8'); template = fs.readFileSync(indexHtmlPath, 'utf-8');
@@ -29,10 +35,12 @@ async function ssrRender(res: http.ServerResponse, version: string) {
return; return;
} }
const serverData = { version };
try { try {
const stream = await renderToReadableStream(<Main />, { // 服务端获取数据
const data = await fetchServerData();
const serverData = { version: data.version, timestamp: data.timestamp };
const stream = await renderToReadableStream(<Main version={data.version} />, {
bootstrapScripts: [] bootstrapScripts: []
}); });
@@ -59,7 +67,7 @@ http.createServer((req, res) => {
const urlPath = req.url?.split('?')[0] || '/'; const urlPath = req.url?.split('?')[0] || '/';
if (urlPath === '/') { if (urlPath === '/') {
ssrRender(res, ''); ssrRender(res);
return; return;
} }
@@ -80,7 +88,7 @@ http.createServer((req, res) => {
} catch { } catch {
} }
ssrRender(res, ''); ssrRender(res);
}).listen(PORT, () => { }).listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`); console.log(`Server running on http://localhost:${PORT}`);
}); });