当前位置: 首页 > article >正文

react中hooks之 React 19 新 Hooks useOptimistic

概述

useOptimistic 是 React 19 引入的新 Hook,用于实现乐观更新(Optimistic Updates)。它允许你在等待异步操作完成时立即更新 UI,提供更好的用户体验。

基本语法

const [optimisticState, addOptimistic] = useOptimistic<State, Patch>(
  state,
  updateFn
);

参数说明

  1. state: 当前状态值

    • 可以是任何类型的值
    • 作为乐观更新的基础状态
  2. updateFn: 更新函数

    • 类型: (currentState: State, patch: Patch) => State
    • 接收当前状态和更新补丁
    • 返回新的乐观状态

返回值

type UseOptimisticReturn<State, Patch> = [
  State,                      // 乐观状态
  (patch: Patch) => void      // 触发乐观更新的函数
];

使用示例

1. 基础点赞功能

function LikeButton({ id, initialLikes }: { id: string; initialLikes: number }) {
  const [likes, setLikes] = useState(initialLikes);
  const [optimisticLikes, addOptimisticLike] = useOptimistic(
    likes,
    (currentLikes: number, addedLikes: number) => currentLikes + addedLikes
  );

  async function handleLike() {
    addOptimisticLike(1); // 立即更新 UI
    
    try {
      const response = await fetch(`/api/like/${id}`, { method: 'POST' });
      const newLikes = await response.json();
      setLikes(newLikes); // 更新实际状态
    } catch (error) {
      // 错误处理
      setLikes(likes); // 回滚到原始状态
    }
  }

  return (
    <button onClick={handleLike}>
      Likes: {optimisticLikes}
    </button>
  );
}

2. 评论列表

interface Comment {
  id: string;
  text: string;
  author: string;
}

function CommentList() {
  const [comments, setComments] = useState<Comment[]>([]);
  const [optimisticComments, addOptimisticComment] = useOptimistic<
    Comment[],
    Comment
  >(
    comments,
    (currentComments, newComment) => [...currentComments, newComment]
  );

  async function handleAddComment(text: string) {
    const optimisticComment = {
      id: 'temp-' + Date.now(),
      text,
      author: 'Current User',
    };
    
    addOptimisticComment(optimisticComment);

    try {
      const response = await fetch('/api/comments', {
        method: 'POST',
        body: JSON.stringify({ text }),
      });
      const savedComment = await response.json();
      setComments([...comments, savedComment]);
    } catch (error) {
      // 错误处理,回滚
      setComments(comments);
    }
  }

  return (
    <div>
      <CommentForm onSubmit={handleAddComment} />
      <ul>
        {optimisticComments.map(comment => (
          <CommentItem key={comment.id} comment={comment} />
        ))}
      </ul>
    </div>
  );
}

3. 复杂状态更新

interface TodoItem {
  id: string;
  text: string;
  completed: boolean;
}

function TodoList() {
  const [todos, setTodos] = useState<TodoItem[]>([]);
  const [optimisticTodos, addOptimisticUpdate] = useOptimistic<
    TodoItem[],
    { id: string; completed: boolean }
  >(
    todos,
    (currentTodos, update) => 
      currentTodos.map(todo => 
        todo.id === update.id 
          ? { ...todo, completed: update.completed }
          : todo
      )
  );

  async function toggleTodo(id: string, completed: boolean) {
    addOptimisticUpdate({ id, completed });

    try {
      await fetch(`/api/todos/${id}`, {
        method: 'PATCH',
        body: JSON.stringify({ completed }),
      });
    } catch (error) {
      // 回滚
      setTodos(todos);
    }
  }

  return (
    <ul>
      {optimisticTodos.map(todo => (
        <TodoItem
          key={todo.id}
          todo={todo}
          onToggle={toggleTodo}
        />
      ))}
    </ul>
  );
}

最佳实践

  1. 错误处理与回滚
function useOptimisticAction<T, P>(
  initialState: T,
  updateFn: (state: T, patch: P) => T,
  actionFn: (patch: P) => Promise<T>
) {
  const [state, setState] = useState<T>(initialState);
  const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);

  async function performAction(patch: P) {
    addOptimistic(patch);
    try {
      const result = await actionFn(patch);
      setState(result);
    } catch (error) {
      setState(state); // 回滚
      throw error;
    }
  }

  return [optimisticState, performAction] as const;
}
  1. 与 Suspense 集成
function AsyncList() {
  return (
    <Suspense fallback={<Skeleton />}>
      <OptimisticList />
    </Suspense>
  );
}

注意事项

  1. 性能考虑:

    • 避免在更新函数中进行复杂计算
    • 合理使用 useMemo 缓存计算结果
    • 注意大型列表的渲染优化
  2. 状态一致性:

    • 保持乐观更新和实际状态的同步
    • 实现合适的回滚机制
    • 处理并发更新情况
  3. 用户体验:

    • 提供适当的加载状态指示
    • 实现平滑的状态转换
    • 处理错误情况下的用户反馈

总结

  1. useOptimistic 优点:

    • 提升用户体验
    • 减少感知延迟
    • 支持复杂状态更新
    • 易于实现回滚
  2. 适用场景:

    • 点赞/收藏功能
    • 评论系统
    • 待办事项列表
    • 表单提交
    • 数据列表操作
  3. 使用建议:

    • 合理处理错误情况
    • 实现优雅的回滚机制
    • 注意状态一致性
    • 优化性能表现

http://www.kler.cn/a/517470.html

相关文章:

  • 【机器学习】穷理至极,观微知著:微积分的哲思之旅与算法之道
  • vim如何设置自动缩进
  • LabVIEW橡胶动态特性测试系统
  • ansible自动化运维实战--script、unarchive和shell模块(6)
  • 7-Zip Mark-of-the-Web绕过漏洞复现(CVE-2025-0411)
  • Qt 5.14.2 学习记录 —— 십칠 窗口和菜单
  • linux系统下的磁盘扩容
  • 前端知识——HTML基础
  • ⚡C++ 中 std::transform 函数深度解析:解锁容器元素转换的奥秘⚡【AI 润色】
  • 低代码开发中的开源与闭源之争
  • 分数之和(题解)
  • 无人机的应用场景有哪些?
  • gesp(C++六级)(1)洛谷:P10250:[GESP样题 六级] 下楼梯
  • Java面试题2025-Spring
  • 【C语言】结构体与共用体深入解析
  • Django创建纯净版项目并启动
  • RNN实现阿尔茨海默症的诊断识别
  • 通过 Visual Studio Code 启动 IPython
  • 在K8S中,Keepalived是如何检测工作节点是否存活的?
  • redis常用命令和内部编码
  • 使用Cline+deepseek实现VsCode自动化编程
  • 51单片机——按键控制LED流水灯
  • 深度学习利用数据加载、预处理和增强数据提高模型的性能
  • C++ lambda表达式
  • Java编程语言:从入门到进阶的全面指南
  • 数仓的数据加工过程-ETL