DEV Community

Jaligama Satyaveer
Jaligama Satyaveer

Posted on

1

React 19 : useOptimistic Hook

React 19 introduced several new features, including the useOptimistic hook.

useOptimistic help us in updating the UI when our async function is in progress.

Lets understand the use case of useOptimistic with an example

  1. When a user likes a post on Instagram.
  2. Client(Instagram app on user device) will make an API call to server for updating the number of likes. (asynchronous action)
  3. Once client receives the response from the server, UI will be updated accordingly with correct number of likes.

If the server is slow, there may be a delay in receiving the response and updating the UI, leading to a poor user experience.

The best way to enhance user experience

  1. User likes a post on Instagram.
  2. UI will display updated likes count without any delay.
  3. Client will make an API call to server. (asynchronous action)
  4. If API call is success, there will be no change in the UI (because we are already displaying updated likes count).
  5. If the API call is failed, like will be removed.

useOptimistic hook assists in managing likes while our asynchronous code (such as an API call in this case) is still underway.

API call Success

API call Failed

Code

import { HeartFilledIcon, HeartIcon } from "@radix-ui/react-icons";
import { Box, Strong, Text } from "@radix-ui/themes";
import { useOptimistic, useState, useTransition } from "react";

const UseOptimisticExample = () => {
  const [likes, setLikes] = useState(100);
  const [isPostLiked, setIsPostLiked] = useState(false);
  const [optimisticData, setOptimisticData] = useOptimistic(
    { likes, isPostLiked },
    (currentState, newLikes) => {
      return { likes: currentState.likes + newLikes, isPostLiked: true };
    }
  );
  const [, startTransition] = useTransition();

  const onLikeClick = () => {
    startTransition(async () => {
      setOptimisticData(1);
      //   Simulating API call
      await new Promise((resolve, reject) => {
        console.log("Request sent to server");
        setTimeout(() => {
          resolve(likes + 1); // To simulate API call success
          //   reject("API call failed"); // To simulate API call failure
        }, 8000);
      })
        .then((newLikes) => {
          console.log("API call success");
          setLikes(newLikes);
          setIsPostLiked(true);
        })
        .catch((error) => {
          console.error(error);
        });
    });
  };

  return (
    <Box py="1" px="2">
      {optimisticData.isPostLiked ? (
        <HeartFilledIcon
          color="red"
          style={{ height: "50px", width: "50px", cursor: "pointer" }}
          onClick={onLikeClick}
        />
      ) : (
        <HeartIcon
          style={{ height: "50px", width: "50px", cursor: "pointer" }}
          onClick={onLikeClick}
        />
      )}
      <br></br>
      <Text>
        <Strong>{optimisticData.likes} Likes</Strong>
      </Text>
    </Box>
  );
};

export default UseOptimisticExample;

Enter fullscreen mode Exit fullscreen mode

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay