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 使用
    • 实现适当的错误处理
    • 注意性能优化
    • 合理组织代码结构
相关推荐
zy happy20 分钟前
RuoyiApp 在vuex,state存储nickname vue2
前端·javascript·小程序·uni-app·vue·ruoyi
小雨青年33 分钟前
Cursor 项目实战:AI播客策划助手(二)—— 多轮交互打磨播客文案的技术实现与实践
前端·人工智能·状态模式·交互
Nan_Shu_6141 小时前
学习:JavaScript(5)
开发语言·javascript·学习
533_1 小时前
[vue3] h函数,阻止事件冒泡
javascript·vue.js·elementui
通往曙光的路上1 小时前
day22_用户授权 头像上传
javascript·vue.js·ecmascript
小光学长1 小时前
基于Vue的儿童手工创意店管理系统as8celp7(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
meichaoWen1 小时前
【Vue】Vue框架的基础知识强化
前端·javascript·vue.js
jingling5551 小时前
Flutter | 基础环境配置和创建flutter项目
前端·flutter
mapbar_front1 小时前
如何判断一个领导值不值得追随
前端
西西学代码1 小时前
Flutter---DragTarget(颜色拖拽选择器)
前端·javascript·flutter