useDeferredValue in React 18

With React 18, a new hook is available which can slow down our UI on purpose 🤯 Why may we need such a hook? 🤔

3 min read


By Joakim Sjøhaug


December 22, 2021

⏲ useDeferredValue

useDeferredValue is a new hook that is part of the concurrent mode patterns being introduced in React 18. The hook exists such that we can introduce an inconsistency in the UI, intentionally.

By default React guarantees that the UI is rendered consistent, always. This means that whatever React is told to render, React will guarantee that the components will reflect the same data that is passed to them.

In most cases this works really well and gives a great user experience, however, there may be cases where an inconsistency can give a better user experience and here useDeferredValue come in handy.

As mentioned useDeferredValue exists such that we can create an inconsistency in the UI. The hook takes two parameters, a value to defer, and an optional config object. Currently the config object is used to tell the maximum time react can defer a value.

const [searchText, setSearchText] = useState("");
const searchTextDeferred = useDeferredValue(searchText);

The block above show a simple example where useDeferredValue is used to create a deferred version of the search text.

🤔 How does it differentiate from debouncing?

If you have been in touch with debouncing, you may think that useDeferredValue and debouncing are the same. In one way, they are doing the same - making it possible to delay a value. However, there is one major difference between the two techniques.

In React 18, useDeferredValue will only make a value "lag behind" if the rendering takes a while. On the other hand, a debounce method will always introduce a lag, it does not matter how fast the computer is.

✨An example

To give a short demonstration of the useDeferredValue hook, we have implemented a simple web application to view and search for players in Fantasy Premier League ⚽️

"To see the effect of the useDeferredValue hook on your machine, throttle your CPU while looking at the example application 🐌"

The web application fetches all players from the Fantasy Premier League API and displays them in one big simple table along with a search field 🤓

There is only one problem. Looking at the gif below, we can see how typing the name of a player in the search field causes stutter.

Text field without a deferred search text

If you, like me, have created large tables with the possibility to search for a value, you would probably have thought about introducing the debounce method now, but wait!

Changing our implementation to use the new useDeferredValue hook on the value of the search field - typing a player’s name suddenly feels more responsive.

Text field with a deferred search text

It’s worth noticing that using useDeferredValue comes with a cost - we are slowing the results with a lag. For most users the lag would be unnoticeable and most important, for users with a slower computer the experience would be better.

👩🏼‍💻 The Implementation

If you want to have a look at our example implementation using the useDeferredValue hook - it is available here🎅🏻

Thanks for reading - and happy holidays! 🎄🎁