useOptimistic react hook

The useOptimistic hook in React 19 is designed to handle optimistic updates. Optimistic updates allow you to update the UI immediately in response to a user action, assuming the operation will succeed, even before receiving confirmation from the server. This creates a smoother and more responsive user experience.

How useOptimistic Works

  1. Initial State: You define the initial state of your data.
  2. Optimistic Update: When a user action occurs, the UI is updated immediately with the expected result.
  3. Server Response Handling: Once the server responds, the UI is updated again to confirm the optimistic update or revert to the original state if the operation fails.
  4. Error Handling: Any errors are caught and handled gracefully.

Examples

Here are five examples to illustrate how useOptimistic can be used:

  1. Liking a Post
   import { useOptimistic } from 'react';

   function LikeButton({ postId }) {
     const [likes, updateLikes] = useOptimistic(async (currentLikes) => {
       const response = await fetch(`/api/like-post/${postId}`, { method: 'POST' });
       if (!response.ok) throw new Error('Failed to like post');
       return currentLikes + 1;
     }, 0);

     return (
       <button onClick={() => updateLikes(likes + 1)}>
         Like ({likes})
       </button>
     );
   }
  1. Adding a Comment
   import { useOptimistic } from 'react';

   function CommentForm({ postId }) {
     const [comments, addComment] = useOptimistic(async (newComment) => {
       const response = await fetch(`/api/add-comment/${postId}`, {
         method: 'POST',
         body: JSON.stringify({ text: newComment }),
       });
       if (!response.ok) throw new Error('Failed to add comment');
       return [...comments, newComment];
     }, []);

     const handleSubmit = (e) => {
       e.preventDefault();
       const newComment = e.target.elements.comment.value;
       addComment(newComment);
     };

     return (
       <form onSubmit={handleSubmit}>
         <input name="comment" type="text" />
         <button type="submit">Add Comment</button>
         <ul>
           {comments.map((comment, index) => (
             <li key={index}>{comment}</li>
           ))}
         </ul>
       </form>
     );
   }
  1. Updating a Profile Name
   import { useOptimistic } from 'react';

   function ProfileEditor() {
     const [name, updateName] = useOptimistic(async (newName) => {
       const response = await fetch('/api/update-name', {
         method: 'POST',
         body: JSON.stringify({ name: newName }),
       });
       if (!response.ok) throw new Error('Failed to update name');
       return newName;
     }, 'John Doe');

     return (
       <div>
         <input
           type="text"
           value={name}
           onChange={(e) => updateName(e.target.value)}
         />
       </div>
     );
   }
  1. Toggling a Todo Item
   import { useOptimistic } from 'react';

   function TodoItem({ todo }) {
     const [completed, toggleCompleted] = useOptimistic(async (currentState) => {
       const response = await fetch(`/api/toggle-todo/${todo.id}`, { method: 'POST' });
       if (!response.ok) throw new Error('Failed to toggle todo');
       return !currentState;
     }, todo.completed);

     return (
       <div>
         <input
           type="checkbox"
           checked={completed}
           onChange={() => toggleCompleted(!completed)}
         />
         {todo.text}
       </div>
     );
   }
  1. Adding an Item to a Cart
   import { useOptimistic } from 'react';

   function AddToCartButton({ itemId }) {
     const [cart, addToCart] = useOptimistic(async (currentCart) => {
       const response = await fetch(`/api/add-to-cart/${itemId}`, { method: 'POST' });
       if (!response.ok) throw new Error('Failed to add to cart');
       return [...currentCart, itemId];
     }, []);

     return (
       <button onClick={() => addToCart([...cart, itemId])}>
         Add to Cart
       </button>
     );
   }

Practice Exercises

Here are five practice exercises to help you get comfortable with useOptimistic:

  1. Exercise 1: Create a form that allows users to submit their email address. Use useOptimistic to optimistically update the UI to show the email in a list before the server confirms the submission.
  2. Exercise 2: Implement a “Follow” button for a social media profile. Use useOptimistic to immediately update the follower count when the button is clicked.
  3. Exercise 3: Build a simple task manager where users can mark tasks as completed. Use useOptimistic to update the task’s status in the UI immediately.
  4. Exercise 4: Create a voting system for a poll. Use useOptimistic to update the vote count for an option as soon as the user votes.
  5. Exercise 5: Develop a shopping list application where users can add items to their list. Use useOptimistic to show the new item in the list immediately after the user adds it.

These exercises should help you get a good grasp of how to use the useOptimistic hook in various scenarios.

Published
Categorized as React