React 19 ------ use() 学习笔记
本文记录 React 19 中
use()API 的核心概念、使用方式、适用场景与常见误区。目标:知道什么时候该用,什么时候不该用。
一、use() 是什么?
use() 是 React 19 引入的一个新的渲染期读取 API,用于在 render 阶段读取:
- Promise(配合 Suspense)
- Context(替代 useContext 的一种更灵活形式)
js
import { use } from "react";
它不是普通 Hook,但只能在 组件或自定义 Hook 中使用。
二、use(promise):声明式等待数据
1. 基本概念
js
const data = use(promise);
-
如果
promisepending- React 会 suspend(挂起)渲染
- 最近的
<Suspense fallback>会显示
-
如果
promiseresolveuse()返回数据,组件继续渲染
-
如果
promisereject / throw- 错误会被抛给最近的 ErrorBoundary
⚠️
use(promise)本身 不处理 loading / error UI
- loading →
<Suspense>- error →
<ErrorBoundary>
2. 标准使用模板(推荐)
jsx
<ErrorBoundary>
<Suspense fallback={<Loading />}>
<User />
</Suspense>
</ErrorBoundary>
js
function User() {
const user = use(userPromise);
return <div>{user.name}</div>;
}
3. 什么是"声明式等待"?
声明式等待 = 不手动管理 loading/error state,而是声明"我依赖这个资源"
对比:
命令式(传统)
js
useEffect + useState + if (loading)
声明式(React 19)
js
use(promise) + <Suspense>
React 负责在「未就绪 / 已就绪 / 出错」之间切换 UI。
4. use(promise) 最重要的前提(必记)
Promise 必须是"稳定的"
❌ 错误示例(最常见坑):
js
function Bad() {
const data = use(fetch("/api/user").then(r => r.json()));
}
问题:
- 每次 render 都创建新 Promise
- 会导致重复请求 / 无限 suspend
- 常见错误:
uncached promise
✅ 正确方向:
- Promise 来自 服务端组件
- 或来自 缓存层 / 框架 / 外部传入
5. use(promise) 推荐 / 不推荐场景
✅ 推荐
- Server Components / SSR 数据流
- 框架(Next / Remix)提供稳定 Promise
- Suspense 驱动的页面级数据
❌ 不推荐
- 普通客户端组件里直接 fetch
- 替代 React Query / SWR
- 复杂客户端交互型数据管理
三、错误如何处理?(非常重要)
1. Suspense vs ErrorBoundary
| 状态 | 处理方式 |
|---|---|
| pending | <Suspense fallback> |
| error | <ErrorBoundary> |
<Suspense>只处理 pending异常(reject / throw)一定交给 ErrorBoundary
2. "错误即异常" vs "错误即数据"
使用 ErrorBoundary(推荐)
- 页面初始化失败
- 系统级错误
- 不可用状态
使用"错误即数据"
js
function fetchSafe() {
return fetch(...).catch(() => ({ error: true }));
}
适合:
- 局部失败
- 可重试 / 可忽略模块
四、use(context):更自由的 useContext
1. 核心能力(一句话)
use(context)可以在条件、分支、早返回中使用
这是它唯一且最重要的能力。
2. 对比 useContext
以前(受 Hook 规则限制)
js
const theme = useContext(ThemeContext);
if (!enabled) return null;
React 19
js
if (!enabled) return null;
const theme = use(ThemeContext);
3. 典型使用场景
- 早返回组件
- 权限 / feature flag
- 多 Context 按需选择
- 平台差异(web / native)
4. 注意事项
use(context)≠ 性能优化- 读取过 context → 更新仍会 re-render
- 简单场景没必要强行替换 useContext
五、常见易混淆点(重点区)
1. use() ≠ 新的数据请求方案
- 它是 渲染模型的一部分
- 不是 fetch / axios 的替代品
2. use(promise) ≠ React Query
- use(promise):声明式、渲染级
- React Query:状态级、客户端交互
3. Suspense ≠ ErrorBoundary
- Suspense:等
- ErrorBoundary:炸了兜底
六、心智模型总结(必记)
use(promise)让 React 控制等待- Promise 必须来自 稳定来源
- pending / success / error 是 渲染结构,不是 state
use(context)解决的是 条件依赖问题
七、一句话总结
use() 不是为了写得更炫,而是为了让"数据依赖"变成声明式的一等公民。