useOptimistic

Хук useOptimistic наразі доступний лише в Canary та експериментальних каналах React. Дізнайтеся більше про канали релізів React тут.

useOptimistic є хуком React, який дозволяє оптимізувати оновлення інтерфейсу.

const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);

Огляд

useOptimistic(state, updateFn)

useOptimistic - це хук React, який дозволяє показувати інший стан під час виконання асинхронної дії. Він приймає деякий стан як аргумент і повертає копію цього стану, який може змінюватися під час виконання асинхронної дії, наприклад, мережевого запиту. Ви надаєте функцію, яка приймає поточний стан і вхідні дані для дії, і повертає оптимістичний стан, який буде використано під час виконання дії.

Цей стан називається "оптимістичним", оскільки він зазвичай використовується для негайного представлення користувачеві результату виконання дії, навіть якщо ця дія насправді потребує часу для завершення.

import { useOptimistic } from 'react';

function AppContainer() {
  const [optimisticState, addOptimistic] = useOptimistic(
    state,
    // updateFn
    (currentState, optimisticValue) => {
      // merge and return new state
      // with optimistic value
    }
  );
}

Дивіться більше прикладів нижче.

Параметри

  • state: значення, яке має бути повернуто спочатку і коли не виконується жодної дії.
  • updateFn(currentState, optimisticValue): функція, яка приймає поточний стан і оптимістичне значення, передане в addOptimistic і повертає отриманий оптимістичний стан. Це має бути чиста функція. updateFn приймає два параметри. currentState і optimisticValue. Значенням, що повертається, буде об'єднане значення currentState і optimisticValue.

Повернення

  • optimisticState: результуючий оптимістичний стан. Він дорівнює стану, якщо тільки дія не очікує на виконання, у цьому випадку він дорівнює значенню, повернутому updateFn.
  • addOptimistic: addOptimistic - диспетчерська функція, яку слід викликати, коли ви маєте оптимістичне оновлення. Вона приймає один аргумент, optimisticValue, будь-якого типу і викликає updateFn зі станом , і optimisticValue.

Використання

Оптимістичне оновлення форм

Хук useOptimistic надає спосіб оптимізованого оновлення інтерфейсу користувача до завершення фонової операції, наприклад, мережевого запиту. У контексті форм ця техніка допомагає зробити програми більш чуйними. Коли користувач надсилає форму, замість того, щоб чекати на відповідь сервера, щоб відобразити зміни, інтерфейс негайно оновлюється з очікуваним результатом.

Наприклад, коли користувач вводить повідомлення у форму і натискає кнопку "Відправити", хук useOptimistic дозволяє повідомленню негайно з'явитися у списку з міткою "Відправлення...", ще до того, як повідомлення буде відправлено на сервер. Такий "оптимістичний" підхід створює враження швидкості та оперативності. Потім форма намагається дійсно відправити повідомлення у фоновому режимі. Як тільки сервер підтвердить, що повідомлення отримано, мітку "Відправлення..." буде видалено.

import { useOptimistic, useState, useRef } from "react";
import { deliverMessage } from "./actions.js";

function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get("message"));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true
      }
    ]
  );

  return (
    <>
      {optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}
      <form action={formAction} ref={formRef}>
        <input type="text" name="message" placeholder="Hello!" />
        <button type="submit">Send</button>
      </form>
    </>
  );
}

export default function App() {
  const [messages, setMessages] = useState([
    { text: "Hello there!", sending: false, key: 1 }
  ]);
  async function sendMessage(formData) {
    const sentMessage = await deliverMessage(formData.get("message"));
    setMessages((messages) => [...messages, { text: sentMessage }]);
  }
  return <Thread messages={messages} sendMessage={sendMessage} />;
}
export async function deliverMessage(message) {
  await new Promise((res) => setTimeout(res, 1000));
  return message;
}
{
  "dependencies": {
    "react": "18.3.0-canary-6db7f4209-20231021",
    "react-dom": "18.3.0-canary-6db7f4209-20231021",
    "react-scripts": "^5.0.0"
  },
  "main": "/index.js",
  "devDependencies": {}
}