0% completed
The useOptimistic
Hook is a new hook that provides a way to optimistically update the user interface before a background operation, like a network request, completes.
In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server’s response to reflect the changes, the interface is immediately updated with the expected outcome.
Here’s how optimistic updates typically work in a form submission scenario:
Immediate UI Update: When a user submits a form, instead of waiting for the server's response, the form's state is updated to reflect the expected outcome (e.g., marking the form as "submitted" or displaying a success message).
Server Request: The form data is then sent to the server asynchronously (e.g., via axios, fetch, etc.), and the request is processed in the background.
Revert or Confirm: If the server confirms the action was successful, the UI remains as it is. If the request fails (e.g., due to a network error), the UI is reverted to its previous state, and an error message can be displayed.
For example, when a user types a message into a form and hits the “Send” button, the useOptimistic
Hook allows the message to immediately appear in the list with a “Sending…” label, even before the message is actually sent to a server. This “optimistic” approach gives the impression of speed and responsiveness. The form then attempts to truly send the message in the background. Once the server confirms the message has been received, the “Sending…” label is removed.
Let's see how this code works in an example:
import { useOptimistic, useState, useRef } from "react"; 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> </> ); } async function deliverMessage(message) { await new Promise((res) => setTimeout(res, 1000)); return message; } 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, { text: sentMessage }]); } return <Thread messages={messages} sendMessage={sendMessage} />; } export default App
Here, the useOptimistic
hook tracks the messages sent whether they are newly sent and if the current state of the sending status is true or not. It then optimistically updates the new message as a sent message and updates the UI.
Optimistic updates offer several benefits, particularly in enhancing the user experience and performance of applications. Here are the key advantages:
A responsive, fast user interface can increase user satisfaction and engagement, leading to higher retention rates. This is what the useOptimistic
hook delivers on. Delays or lag in feedback can cause frustration and might lead users to abandon the app or website. So, with this hook you can improve on the User Experience while on your application.
.....
.....
.....