React 18.3 新增的 use API,可以直接从 react 包中导入:
import { use } from 'react';
这个 use 是 React 团队为 Server Components(RSC) 和 Suspense 异步数据 引入的一个新 Hook,跟以前的 useState、useEffect 完全不同。
详细解释:
use 的作用use 的核心用途是:
换句话说,use 可以让你像同步代码一样写异步逻辑,不需要 useEffect + useState 手动处理。
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 会先显示 “加载中...”use 也可以直接读取上下文,代替 useContext:
import { createContext, use } from 'react';
const ThemeContext = createContext('light');
function Child() {
const theme = use(ThemeContext); // 直接用 use 获取 context
return <p>当前主题:{theme}</p>;
}
use(promise),需要配合 Suspense。use 主要是为 异步数据流和 Context 提供简化语法。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 时的优势:
| 场景 | 传统写法(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>
);
}
| 场景 | 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>;
}
传统 Hooks(useState + useEffect + useContext):
use 新写法: