useOptimistic
useOptimistic
— это хук React, который позволяет оптимистично обновлять UI.
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) => {
// объедините и верните новое состояние
// с оптимистичным значением
}
);
}
Посмотрите больше примеров ниже.
Параметры
state
: значение, которое вернётся изначально, и во всех случаях, когда нет действий в состоянии ожидания.updateFn(currentState, optimisticValue)
: функция, которая принимает текущее состояние и оптимистичное значение, переданное вaddOptimistic
, и возвращает результирующее оптимистичное состояние. Функция должна быть чистой.updateFn
принимает два параметра:currentState
иoptimisticValue
. Возвращаемое значение будет результатом объединенияcurrentState
иoptimisticValue
.
Возвращаемое значение
optimisticState
: Результат оптимистичного состояния. Оно равноstate
, пока нет действий в состоянии ожидания, иначе будет равно значению, возвращённому изupdateFn
.addOptimistic
:addOptimistic
— это функция-диспетчер, которая вызывается при оптимистичном обновлении. Она принимает только один аргументoptimisticValue
любого типа и вызоветupdateFn
с параметрамиstate
andoptimisticValue
.
Использование
Оптимистичное обновление форм
Хук 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> (Отправка...)</small>} </div> ))} <form action={formAction} ref={formRef}> <input type="text" name="message" placeholder="Hello!" /> <button type="submit">Отправить</button> </form> </> ); } export default function App() { const [messages, setMessages] = useState([ { text: "Привет!", 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} />; }