🪝 Introduction to useOptimistic
The useOptimistic Hook is a React Hook that helps create an optimistic user interface. Instead of waiting for a server request to complete, the UI updates immediately, giving users instant feedback. If the server operation succeeds, the optimistic state is confirmed. If it fails, the UI can revert to its previous state.
Important
🎯 Why Use useOptimistic?
In many applications, waiting for a network request before updating the interface can make the application feel slow. useOptimistic improves the user experience by showing the expected result immediately while the server request is still in progress.
- Provides instant visual feedback.
- Makes applications feel faster.
- Improves user experience during network requests.
- Works well with server actions and asynchronous operations.
⚙️ Syntax
Basic Syntax
const [optimisticState, addOptimistic] =
useOptimistic(initialState, updateFn);| Part | Description |
|---|---|
| optimisticState | The temporary state shown to the user. |
| addOptimistic | Applies an optimistic update before the server responds. |
| initialState | The current confirmed state. |
| updateFn | A function that returns the optimistic version of the state. |
🔄 How useOptimistic Works
💻 Basic Example
Optimistic List Update
import { useOptimistic } from "react";
function TodoList({ todos }) {
const [optimisticTodos, addTodo] = useOptimistic(
todos,
(currentTodos, newTodo) => [
...currentTodos,
newTodo
]
);
async function handleAdd() {
addTodo({
id: Date.now(),
text: "New Todo"
});
// Send request to the server...
}
return (
<>
<button onClick={handleAdd}>
Add Todo
</button>
<ul>
{optimisticTodos.map(todo => (
<li key={todo.id}>
{todo.text}
</li>
))}
</ul>
</>
);
}As soon as the button is clicked, the new todo appears in the interface without waiting for the server response, creating a smooth and responsive user experience.
📨 Example: Sending a Message
Optimistic Chat Message
import { useOptimistic } from "react";
function Chat({ messages }) {
const [optimisticMessages, addMessage] =
useOptimistic(
messages,
(current, message) => [
...current,
message
]
);
async function sendMessage(text) {
addMessage({
id: Date.now(),
text,
pending: true
});
// Send message to the server...
}
}Users immediately see their message in the conversation while the application communicates with the server in the background.
📊 Normal Update vs Optimistic Update
| Traditional Update | Optimistic Update |
|---|---|
| Wait for server response. | Update the UI immediately. |
| User may notice a delay. | User receives instant feedback. |
| UI changes only after success. | UI changes first, then confirms or reverts. |
| Better for critical confirmation. | Better for responsive experiences. |
🎯 Common Use Cases
Display newly added comments immediately while the server saves them.
Instantly update like counts before the server confirms the action.
Show sent messages immediately for a smoother chat experience.
Add, edit, or remove tasks instantly while synchronization happens in the background.
⚠️ Things to Consider
- Handle server errors gracefully.
- Provide a way to revert optimistic updates if a request fails.
- Use optimistic updates only when temporary inconsistencies are acceptable.
- Keep optimistic update logic simple and predictable.
✅ Best Practices
- Use useOptimistic for interactions that benefit from immediate feedback.
- Keep optimistic updates lightweight.
- Synchronize the optimistic state with the confirmed server state.
- Display loading or pending indicators when appropriate.
- Always handle failure scenarios to maintain data consistency.
📚 Official Resource
Learn more about useOptimistic in the official React documentation at React useOptimistic Documentation.