二、场景一:异步读取 Promise
这是 use 最强大的功能。你可以直接在组件中 use(promise)。
1. 基础用法
import { use } from 'react';
function Message({ messagePromise }) {
// 直接读取 Promise 的值!
const messageContent = use(messagePromise);
return <p>来自服务端的消息: {messageContent}</p>;
}
2. 配合 Suspense 与 Error Boundary
use 并不是直接在组件里返回 pending 状态,而是会**挂起(Suspend)**当前组件的执行。这意味着你必须配合 Suspense 使用。
import { Suspense, use } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
function App() {
const messagePromise = fetchMessage(); // 获取 Promise(通常在父组件或外部发起)
return (
<ErrorBoundary fallback={<p>⚠️ 加载失败!</p>}>
<Suspense fallback={<p>⌛ 正在拼命加载中...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
</ErrorBoundary>
);
}
3. 注意点:不要在组件内创建 Promise
这是新手最容易踩的坑。如果在组件内部每次渲染都重新 fetch 创建一个新的 Promise,会导致组件无限挂起并死循环。
❌ 错误写法:
function Message() {
const messagePromise = fetch('/api/msg'); // 每次渲染都重新 fetch,大错特错!
const content = use(messagePromise);
return <p>{content}</p>;
}
✅ 正确做法:
- 将 Promise 作为 props 传递。
- 或者使用
cache(React 19 提供的新 API)对 Promise 进行缓存。
三、场景二:条件化读取 Context
这是 use 另一个让人惊艳的特性:它可以在条件判断或循环中读取 Context!
1. 突破 Hook 限制
在 React 19 之前,如果你想根据某个条件读取 Context,你必须在组件顶部无条件调用 useContext。
❌ 旧写法:
function Button({ showTheme }) {
const theme = useContext(ThemeContext); // 无论用不用,都得调用
if (!showTheme) return <button>Default Button</button>;
return <button style={{ color: theme.color }}>Themed Button</button>;
}
✅ React 19 use 写法:
function Button({ showTheme }) {
if (!showTheme) return <button>Default Button</button>;
// 只有在需要时才读取 Context!
const theme = use(ThemeContext);
return <button style={{ color: theme.color }}>Themed Button</button>;
}
2. 为什么这很重要?
这不仅让代码更简洁,还能优化性能。如果你的组件在某些分支下不需要 Context,那么当 Context 变化时,该组件可能不需要重新渲染。