No matter what type of app you’re building, you’re going to need to fetch data, display that data to a user, and enable the user to interact with and update that data. This interaction/updating phase is often asynchronous. This presents you, the developer, an opportunity to provide a range of differing experiences depending on the circumstances.
In certain cases, you can leverage what is known as optimistic UI updates for an improved, snappier user experience as compared to a traditional “loading” experience (further reading: True Lies Of Optimistic User Interfaces).
*This post is part of 1 of 2. See part 2 here “Loading” and Optimistic UI Updates in React using Promises and setState.
They aren’t suited for every use case, but selectively making use of optimistic UI updates throughout your application can have a big impact on the quality of user experience for relatively little cost/complexity!
The examples and videos linked to are part of my egghead.io course: Optimistic UI Updates in React 🔗. The course is just 25 minutes total, so head on over and check out the course overview (free) to get a feel for what the course is all about.
In this first example, I’m going to break down the process of building a Twitter-like UI where a user can “like” a tweet and dig into the challenges of optimistically updating the UI to reflect:
We’ll look at accounting for request failures, reverting state, and some edge cases along the way.
There is no accompanying code or video for this section, but I want to call out CodeSandbox.io as an absolute game changer for being able to quickly prototype and/or share examples and mini-projects. If you haven’t already, go check it out and give it a spin https://codesandbox.io/!
First, we’ll add an
onClickLike method to our React component. Upon a user clicking the heart icon, it will immediately update state before firing off a request. We will toggle the “liked” status of the tweet by updating component state based on previous state, using a setState updater function. We’ll then appropriately increment or decrement the target tweet’s
likes property and add or remove the
tweetId from the
React’s setState accepts an updater function that given current state returns new state. To better define and manage our setState usages, we can extract our inlined setState function to a setState updater factory. This enables us to give it a descriptive name and define its required arguments. This approach can ease future reuse, refactoring and composition for updating component state in our application.
By extracting our setState function to this
setTweetLike(tweetId, newLiked) we can easily reuse it when it comes time to revert state upon failure.
Optimistic UI updates come with challenges that can vary for every use case. In our scenario of “liking a tweet”, one challenge that we face is preventing doubly updating and reverting state in the event of the user clicking “like” in rapid succession. In the case of a request failure our current solution results in the false impression that the tweet was successfully liked.
One solution that fits our use case is to simply raise and lower a boolean flag to indicate whether a like tweet request is pending or not. Using this flag, we can short circuit our
onClickLikemethod to “do nothing” if a request is already pending. Since we don’t require this information in our render method or on component state, we can simplify this further by making use of a class instance property to store this value.
TL;DR By assuming response success and updating state/UI immediately upon user action, you can provide much snappier experiences for your users. You’ll have to account for failure cases and other special things along the way. React and component state make this pleasant.
I hope you’ve found this information useful and that it adds value for you in your projects and career 😃
Don’t forget to check out the full course over at https://egghead.io/courses/optimistic-ui-updates-in-react 🔗, leave a comment, share and/or reach out at https://twitter.com/erikaybar_ 👋🏼