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
接受两个参数。currentState
和optimisticValue
。返回值将是currentState
和optimisticValue
的合并值。
返回值
optimisticState
:产生的乐观状态。它等于state
,除非有操作挂起,在这种情况下,它等于updateFn
返回的值。addOptimistic
:addOptimistic
是在进行乐观更新时调用的调度函数。它接受一个任意类型的参数optimisticValue
,并将使用state
和optimisticValue
调用updateFn
。
用法
表单的乐观更新
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} />; }