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
新写法: