在 React 19 中,use
是一个新的 Hook,用于在客户端组件中直接消费由父组件(通常是 Server Component)传递下来的 Promise ,同时与 Suspense
和错误边界集成。这种模式可以让你在客户端组件中安全地处理异步数据,同时保持数据获取的早期发起。
场景解析
你的问题描述的场景是:
- 父组件是 Server Component:负责发起数据请求(如获取轮播图图片列表),生成一个 Promise。
- 子组件
Content
是 Client Component :因为需要交互(如轮播图滑动),不能使用async/await
。 - 目标 :将父组件的 Promise 传递给子组件,子组件用
use
解析它。
具体实现步骤
1. 父组件(Server Component):发起请求并传递 Promise
jsx
// 父组件(Server Component)
async function ParentComponent() {
// 在 Server Component 中发起请求,生成 Promise
const carouselPromise = fetchCarouselData();
return (
<Suspense fallback={<div>加载轮播图中...</div>}>
{/* 将 Promise 作为 prop 传递给子组件 */}
<Content carouselPromise={carouselPromise} />
</Suspense>
);
}
2. 子组件(Client Component):用 use
解析 Promise
jsx
// 子组件(Client Component)
'use client'; // 标记为客户端组件
import { use } from 'react';
function Content({ carouselPromise }) {
// 用 use 解析父组件传递的 Promise
const carouselData = use(carouselPromise);
// 渲染轮播图(需要客户端交互)
return (
<Carousel>
{carouselData.map((image) => (
<img key={image.id} src={image.url} />
))}
</Carousel>
);
}
关键点解释
use
的作用 :
类似于await
,但专为 React 组件设计。它会暂停组件渲染,直到 Promise 解决,并自动与最近的Suspense
配合显示加载状态。- 为什么在父组件发起请求 :
Server Component 可以在服务端提前发起请求,客户端组件只需消费已发起的 Promise,减少客户端等待时间。 - 为什么不用
useEffect
:
useEffect
在客户端运行时才发起请求,会导致延迟。而父组件提前发起请求,子组件用use
直接消费,数据获取更早开始。 - 与
async/await
的区别 :
客户端组件不能使用async/await
,但use
允许在客户端组件中以同步语法处理异步数据,同时保持组件逻辑清晰。
对比传统方案(useEffect
)
传统方式(不推荐)
jsx
// 子组件(Client Component)
'use client';
import { useState, useEffect } from 'react';
function Content() {
const [carouselData, setCarouselData] = useState(null);
useEffect(() => {
// 在客户端发起请求,导致延迟
fetchCarouselData().then(setCarouselData);
}, []);
if (!carouselData) return <div>加载中...</div>;
return <Carousel>{/* ... */}</Carousel>;
}
缺点:数据获取从客户端开始,加载时间更长,无法利用服务端提前发起的优势。
use
方案(推荐)
jsx
// 子组件(Client Component)
'use client';
import { use } from 'react';
function Content({ carouselPromise }) {
const carouselData = use(carouselPromise); // 直接消费服务端发起的 Promise
return <Carousel>{/* ... */}</Carousel>;
}
优势:数据请求在服务端提前发起,客户端直接消费结果,加载更快,代码更简洁。
总结
use
的定位 :专为在客户端组件中消费服务端发起的 Promise 设计,替代useEffect
+ 手动状态管理。- 适用场景:需要客户端交互的组件(如轮播图、表单),但数据获取需在服务端提前完成。
- 核心价值:统一服务端与客户端的异步数据流,提升性能,简化代码。