React 18.3 新增的 use
API,可以直接从 react
包中导入:
import { use } from 'react';
这个 use
是 React 团队为 Server Components(RSC) 和 Suspense 异步数据 引入的一个新 Hook,跟以前的 useState
、useEffect
完全不同。
详细解释:
1. use
的作用
use
的核心用途是:
- 在组件中直接读取 Promise(或上下文)值
- 配合 Suspense 处理异步数据加载
- 简化 React Server Components 的异步逻辑
换句话说,use
可以让你像同步代码一样写异步逻辑,不需要 useEffect
+ useState
手动处理。
2. 基本用法
读取 Promise
import { use } from 'react';
function DataComponent({ promise }: { promise: Promise<string> }) {
const data = use(promise); // 直接读取 Promise 的结果
return <div>数据:{data}</div>;
}
- 如果
promise
还没完成,组件会自动 挂起(suspend),等待Suspense
的 fallback。 - 如果
promise
失败,会触发 Error Boundary。
配合 Suspense
使用
import { Suspense, use } from 'react';
function fetchData() {
return new Promise<string>((resolve) => {
setTimeout(() => resolve('Hello from Server!'), 2000);
});
}
function AsyncComponent() {
const data = use(fetchData());
return <p>{data}</p>;
}
export default function App() {
return (
<Suspense fallback={<p>加载中...</p>}>
<AsyncComponent />
</Suspense>
);
}
- 页面初始渲染时,
use(fetchData())
会挂起 2 秒 Suspense
会先显示 “加载中...”- Promise 结束后组件重新渲染,显示数据
读取 React Context
use
也可以直接读取上下文,代替 useContext
:
import { createContext, use } from 'react';
const ThemeContext = createContext('light');
function Child() {
const theme = use(ThemeContext); // 直接用 use 获取 context
return <p>当前主题:{theme}</p>;
}
3. 注意事项
- 只能在 Server Components 或支持 RSC 的环境使用(Next.js 13+ Server Components)。
- 客户端组件如果使用
use(promise)
,需要配合Suspense
。 - 目前
use
主要是为 异步数据流和 Context 提供简化语法。
4. 为什么要用 use
以前在 React 里想处理异步数据,你可能要写这样:
function OldWay() {
const [data, setData] = useState<string | null>(null);
useEffect(() => {
fetch('/api/data')
.then(res => res.text())
.then(setData);
}, []);
if (!data) return <p>加载中...</p>;
return <p>{data}</p>;
}
而现在用 use
:
function NewWay() {
const data = use(fetch('/api/data').then(res => res.text()));
return <p>{data}</p>;
}
更像同步代码,并且可以天然配合 Suspense 做流式渲染。
如果你用 Next.js 13+,这个 use
特别适合放在 Server Components 里直接用异步函数返回的数据。
优势对比
下面是 React 18.3+ use
的对比总结表,展示它在处理 异步数据 和 Context 时的优势:
1. 异步数据加载对比
场景 | 传统写法(useState + useEffect) | 新写法(use + Suspense) |
---|---|---|
代码长度 | 冗长,需要状态管理、effect、loading 判断 | 简洁,直接读取 Promise |
异步状态管理 | 需要 useState 存数据 + loading 状态 |
Suspense 自动处理挂起和恢复 |
异常处理 | 需要手动 try/catch + 错误状态 |
Error Boundary 自动捕获 |
服务端渲染(SSR) | 必须先渲染 loading,再通过水合更新 | 可在 Server Components 流式返回数据 |
示例对比:
传统写法:
function OldWay() {
const [data, setData] = useState<string | null>(null);
useEffect(() => {
fetch('/api/data').then(res => res.text()).then(setData);
}, []);
if (!data) return <p>加载中...</p>;
return <p>{data}</p>;
}
新写法:
import { use, Suspense } from 'react';
function NewWay() {
const data = use(fetch('/api/data').then(res => res.text()));
return <p>{data}</p>;
}
export default function App() {
return (
<Suspense fallback={<p>加载中...</p>}>
<NewWay />
</Suspense>
);
}
2. Context 使用对比
场景 | useContext 传统写法 |
use 新写法 |
---|---|---|
获取 Context | const value = useContext(MyContext) |
const value = use(MyContext) |
代码简洁度 | 多一个 useContext 调用 |
直接用 use ,统一 API |
Suspense 支持 | 手动控制 | 自动兼容 Suspense |
示例:
import { createContext, use } from 'react';
const ThemeContext = createContext('light');
function Child() {
const theme = use(ThemeContext); // 更简洁
return <p>当前主题:{theme}</p>;
}
3. 总结
传统 Hooks(
useState
+useEffect
+useContext
):- 适合客户端组件
- 需要手动管理异步状态和错误
use
新写法:- 简化异步逻辑
- 自动挂起配合 Suspense
- 更自然支持 Server Components