react19新API之use()用法总结

React use() Hook 使用指南

概述

use() 是 React 19 引入的新 Hook,它允许你在组件内部直接使用 Promise、Context 和其他可订阅的值。它是一个更通用的数据获取和订阅机制。

基本语法

typescript 复制代码
const value = use(resource);

主要用途

1. Promise 处理

typescript 复制代码
function UserDetails({ userId }: { userId: string }) {
  const user = use(fetchUser(userId));
  // 如果 Promise 还未解决,组件会被挂起
  // 一旦 Promise resolved,组件会重新渲染

  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

2. Context 使用

typescript 复制代码
function Button() {
  const theme = use(ThemeContext);
  // 等同于 useContext(ThemeContext)
  
  return (
    <button className={theme.buttonClass}>
      Click me
    </button>
  );
}

3. 条件性使用

typescript 复制代码
function DataView({ shouldFetch }: { shouldFetch: boolean }) {
  if (shouldFetch) {
    // use() 可以在条件语句中使用
    const data = use(fetchData());
    return <div>{data.content}</div>;
  }
  return <div>Not fetching</div>;
}

高级用法

1. 并行数据获取

typescript 复制代码
function UserProfile({ userId }: { userId: string }) {
  const [user, posts, friends] = use(Promise.all([
    fetchUser(userId),
    fetchUserPosts(userId),
    fetchUserFriends(userId)
  ]));

  return (
    <div>
      <UserInfo user={user} />
      <PostList posts={posts} />
      <FriendList friends={friends} />
    </div>
  );
}

2. 嵌套组件中使用

typescript 复制代码
function Comments({ postId }: { postId: string }) {
  return (
    <Suspense fallback={<Spinner />}>
      <AsyncComments postId={postId} />
    </Suspense>
  );
}

function AsyncComments({ postId }: { postId: string }) {
  const comments = use(fetchComments(postId));
  
  return (
    <ul>
      {comments.map(comment => (
        <CommentItem key={comment.id} comment={comment} />
      ))}
    </ul>
  );
}

3. 自定义资源

typescript 复制代码
function createResource<T>(promise: Promise<T>) {
  let status = 'pending';
  let result: T;
  let error: Error;
  
  const suspender = promise.then(
    (data) => {
      status = 'success';
      result = data;
    },
    (err) => {
      status = 'error';
      error = err;
    }
  );

  return {
    read() {
      switch (status) {
        case 'pending':
          throw suspender;
        case 'error':
          throw error;
        case 'success':
          return result;
      }
    }
  };
}

function DataComponent() {
  const resource = useMemo(() => createResource(fetchData()), []);
  const data = use(resource);
  return <div>{data}</div>;
}

最佳实践

1. 错误边界处理

typescript 复制代码
function ErrorBoundary({ children }: { children: React.ReactNode }) {
  return (
    <Suspense fallback={<Spinner />}>
      <ErrorBoundaryInner>
        {children}
      </ErrorBoundaryInner>
    </Suspense>
  );
}

function DataComponent() {
  return (
    <ErrorBoundary>
      <AsyncContent />
    </ErrorBoundary>
  );
}

2. 缓存和预加载

typescript 复制代码
const cache = new Map();

function fetchWithCache(key: string) {
  if (!cache.has(key)) {
    cache.set(key, fetchData(key));
  }
  return cache.get(key);
}

function PreloadedData({ id }: { id: string }) {
  // 预加载数据
  const data = use(fetchWithCache(id));
  return <div>{data}</div>;
}

注意事项

  1. 使用限制:

    • 只能在组件内部使用
    • 需要配合 Suspense 使用
    • 不能在事件处理器中使用
  2. 性能考虑:

    • 合理使用缓存机制
    • 避免重复创建资源
    • 考虑数据预加载
  3. 错误处理:

    • 使用错误边界捕获异常
    • 提供合适的加载状态
    • 实现优雅的降级处理

总结

  1. use() 的优势:

    • 简化异步数据获取
    • 支持条件性使用
    • 更好的类型推断
    • 统一的资源使用方式
  2. 适用场景:

    • 数据获取
    • Context 消费
    • 自定义订阅
    • 并行数据加载
  3. 使用建议:

    • 配合 Suspense 使用
    • 实现适当的错误处理
    • 注意性能优化
    • 合理组织代码结构
相关推荐
程序员清洒3 小时前
Flutter for OpenHarmony:GridView — 网格布局实现
android·前端·学习·flutter·华为
VX:Fegn08953 小时前
计算机毕业设计|基于ssm + vue超市管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·后端·课程设计
0思必得04 小时前
[Web自动化] 反爬虫
前端·爬虫·python·selenium·自动化
LawrenceLan4 小时前
Flutter 零基础入门(二十六):StatefulWidget 与状态更新 setState
开发语言·前端·flutter·dart
秋秋小事4 小时前
TypeScript 模版字面量与类型操作
前端·typescript
2401_892000524 小时前
Flutter for OpenHarmony 猫咪管家App实战 - 添加提醒实现
前端·javascript·flutter
Yolanda945 小时前
【项目经验】vue h5移动端禁止缩放
前端·javascript·vue.js
广州华水科技6 小时前
单北斗GNSS形变监测一体机在基础设施安全中的应用与技术优势
前端
EndingCoder6 小时前
案例研究:从 JavaScript 迁移到 TypeScript
开发语言·前端·javascript·性能优化·typescript
阿珊和她的猫7 小时前
React 路由:构建单页面应用的导航系统
前端·react.js·状态模式