自学内容网 自学内容网

react19新API之use()用法总结

React use() Hook 使用指南

概述

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

基本语法

const value = use(resource);

主要用途

1. Promise 处理

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 使用

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

3. 条件性使用

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

高级用法

1. 并行数据获取

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. 嵌套组件中使用

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. 自定义资源

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. 错误边界处理

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

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

2. 缓存和预加载

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 使用
    • 实现适当的错误处理
    • 注意性能优化
    • 合理组织代码结构

原文地址:https://blog.csdn.net/qq_34645412/article/details/145291245

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!