useOptimistic

useOptimisticReact 19 版本中提供的 Hooks,用于在应用程序中实现 UI 的乐观更新,允许你在后台操作,例如网络请求时立即更新 UI,而不是等到请求结果返回

import { useOptimistic } from "react";
 
export function Component() {
  const [optValue, setOptValue] = useOptimistic(
    currentValue,
    optUpdateFunction,
  );
 
  return (
    /* template */
  );
}

useOptimistic Hook 接收两个参数:

  • cuttentValue - 你想要乐观管理的状态
  • optUpdateFunction - 根据当前状态和新数据计算乐观值的函数

返回两个包含两个值的数组

  • optValue - 应该在 UI 渲染中乐观展示的值
  • setOptValue - 用于更新乐观值的函数,通常在实际状态更新发生之前调用。

示例

import { useOptimistic, useState } from "react";
 
const addTodoToAPI = async (todo) => {
  // Simulating an API call
  await new Promise((resolve) =>
    setTimeout(resolve, 1000),
  );
  return { id: Date.now(), text: todo };
};
 
export function TodoList() {
  const [todos, setTodos] = useState([]);
  const [optimisticTodos, addOptimisticTodo] =
    useOptimistic(
      todos,
      (currentTodos, newTodo) => [
        ...currentTodos,
        {
          id: "temp",
          text: newTodo,
          pending: true,
        },
      ],
    );
 
  const addTodo = async (formData) => {
    const todo = formData.get("todo");
    addOptimisticTodo(todo);
    const newTodo = await addTodoToAPI(todo);
    setTodos((currentTodos) => [
      ...currentTodos,
      newTodo,
    ]);
  };
 
  return (
    <div>
      <form action={addTodo}>
        <input type="text" name="todo" />
        <button type="submit">Add Todo</button>
      </form>
      <ul>
        {optimisticTodos.map((todo) => (
          <li
            key={todo.id}
            style={{
              opacity: todo.pending ? 0.5 : 1,
            }}
          >
            {todo.text}
          </li>
        ))}
      </ul>
    </div>
  );
}

优点

  • 改进感知性能:通过提供即时反馈,useOptimistic增强应用程序的响应能力,使用户感觉更快、更流畅。
  • 更好的用户体验:用户不必等待服务器响应即可看到其操作的结果,从而实现与应用程序更流畅、更具吸引力的交互。
  • 优雅回退:如果乐观更新失败(例如由于网络错误),React 会自动恢复到实际状态,因此 UI 与应用程序的数据保持一致。

参考

双链