useOptimistic

useOptimistic 是一個 React Hook,可讓你以樂觀的方式更新 UI。

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

參考

useOptimistic(state, updateFn)

useOptimistic 是一個 React Hook,可讓你顯示不同的狀態,同時非同步動作正在進行中。它接受一些狀態作為參數,並返回該狀態的副本,在執行非同步動作(例如網路請求)期間,該副本可能不同。你提供一個函式,它接受目前的狀態和動作的輸入,並返回在動作待處理時要使用的樂觀狀態。

此狀態稱為「樂觀」狀態,因為它通常用於立即向使用者顯示執行動作的結果,即使動作實際上需要時間才能完成。

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 接受兩個參數。currentStateoptimisticValue。返回值將是 currentStateoptimisticValue 的合併值。

回傳值

  • optimisticState:產生的樂觀狀態。它等於 state,除非有動作待處理,在這種情況下,它等於 updateFn 返回的值。
  • addOptimisticaddOptimistic 是當您有樂觀更新時要呼叫的調度函式。它接受一個任何類型的參數 optimisticValue,並會使用 stateoptimisticValue 呼叫 updateFn

用法

表單的樂觀更新

useOptimistic Hook 提供了一種在背景操作(例如網路請求)完成之前,以樂觀的方式更新使用者介面的方法。在表單的上下文中,此技術有助於讓應用程式感覺更具回應性。當使用者提交表單時,介面會立即以預期的結果更新,而不是等待伺服器的回應來反映變更。

例如,當使用者在表單中輸入訊息並按下「傳送」按鈕時,useOptimistic Hook 允許訊息立即出現在清單中,並帶有「傳送中…」標籤,即使訊息實際上尚未傳送到伺服器。這種「樂觀」的方法給人一種速度快且回應迅速的印象。然後,表單會嘗試在背景中真正傳送訊息。一旦伺服器確認已收到訊息,「傳送中…」標籤就會被移除。

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} />;
}