83 lines
1.5 KiB
Markdown
83 lines
1.5 KiB
Markdown
---
|
|
title: 使用组件组合实现并行数据获取
|
|
impact: CRITICAL
|
|
impactDescription: 消除服务端瀑布请求
|
|
tags: server, rsc, parallel-fetching, composition
|
|
---
|
|
|
|
## 使用组件组合实现并行数据获取
|
|
|
|
React 服务端组件在组件树中按顺序执行。通过组合的方式重构代码,以实现并行数据获取。
|
|
|
|
**错误写法(Sidebar 等待 Page 的 fetch 完成后才执行):**
|
|
|
|
```tsx
|
|
export default async function Page() {
|
|
const header = await fetchHeader()
|
|
return (
|
|
<div>
|
|
<div>{header}</div>
|
|
<Sidebar />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
async function Sidebar() {
|
|
const items = await fetchSidebarItems()
|
|
return <nav>{items.map(renderItem)}</nav>
|
|
}
|
|
```
|
|
|
|
**正确写法(两者同时发起 fetch):**
|
|
|
|
```tsx
|
|
async function Header() {
|
|
const data = await fetchHeader()
|
|
return <div>{data}</div>
|
|
}
|
|
|
|
async function Sidebar() {
|
|
const items = await fetchSidebarItems()
|
|
return <nav>{items.map(renderItem)}</nav>
|
|
}
|
|
|
|
export default function Page() {
|
|
return (
|
|
<div>
|
|
<Header />
|
|
<Sidebar />
|
|
</div>
|
|
)
|
|
}
|
|
```
|
|
|
|
**另一种方案(使用 children prop):**
|
|
|
|
```tsx
|
|
async function Header() {
|
|
const data = await fetchHeader()
|
|
return <div>{data}</div>
|
|
}
|
|
|
|
async function Sidebar() {
|
|
const items = await fetchSidebarItems()
|
|
return <nav>{items.map(renderItem)}</nav>
|
|
}
|
|
|
|
function Layout({ children }: { children: ReactNode }) {
|
|
return (
|
|
<div>
|
|
<Header />
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default function Page() {
|
|
return (
|
|
<Layout>
|
|
<Sidebar />
|
|
</Layout>
|
|
)
|
|
}
|