DEV Community

Nicolás Montone
Nicolás Montone

Posted on

Optimistic UI with SWR2

Optimistic UI is a design philosophy that focuses on creating a positive user experience by anticipating and addressing potential setbacks and obstacles. This approach involves designing systems and processes that are resilient and flexible, allowing them to adapt to changing circumstances and unexpected events.

One way to implement optimistic UI is through the use of SWR2, a library for React made by Vercel that allows developers to easily fetch and cache data in real-time. With SWR2, developers can create fast, responsive, and resilient applications, even in the face of network disruptions or server downtime.

For example, let's consider Twitter likes, built with SWR2. 
To implement an optimistic UI in this app, we can use SWR2's mutate function to update the list of to-do items on the client-side immediately, without waiting for a response from the server. This way, if the network connection is lost or the server is unavailable, the changes will still be reflected on the user's screen, providing a seamless and uninterrupted experience.

Let's say we have an API that sends the like to the server:

await addLike(tweetId);

const React, { useCallback } from 'react';

import { useSWR } from 'swr';

const LikeButton = React.memo(({ tweetId }: Props) => {
  const { mutate, data } = useSWR(`/api/tweets/${tweetId}/likes`);

  // update the number of likes on the client-side
  const handleLikeButtonClick = useCallback(() => {
    mutate(addLike(tweetId), {
      optimisticData: data + 1,
    });
  }, [data, mutate, tweetId]);

  return (
    <button onClick={handleLikeButtonClick}>
      {data} Likes
    </button>
  );
});

export default LikeButton
Enter fullscreen mode Exit fullscreen mode

In this example, we use the mutate function to update the number of likes on the client-side immediately, without waiting for a response from the server. This way, if the network connection is lost or the server is unavailable, the changes will still be reflected on the user's screen, providing a seamless and uninterrupted experience.
Additionally, we can use SWR2's error and revalidate functions to handle any potential errors or conflicts that may arise. For instance, if the server responds with an error or a conflicting message, we can use the error function to display a notification to the user, and the revalidate function to automatically retry the request and resolve the issue.

See more about SWR2 here.

Here is how it works in real life:

As you can see, the like button and the like count change instantly and don't wait for the server's response. The Instant gratification of the immediate feedback creates a smooth a nice experience. 

In this case, I set to offline the network throttling and after the request failure, the UI instantly rollback to the source of truth that was the last state before the like. In this case, as a silent error (the app doesn't notify you that there was an error, just fails in background).

Overall, optimistic UI is a powerful approach that can help create user-friendly and resilient applications. However, it is important to remember that it is just one approach and not always the correct solution for every situation. In some cases, it may be more appropriate to use other design philosophies or techniques to achieve the desired user experience. It is important for developers to carefully consider their options and choose the approach that best fits the needs of their application and their users.

We are only trying to give the most dynamic and fast experience to the user, despite all the blockers that we have, such as latency. 
I highly recommend this blog of Guillermo Rouch talking about this topic and more.

Top comments (0)