DEV Community

aldrin
aldrin

Posted on • Updated on

React 18 things : useDeferredValue

References:
React docs: useDeferredValue
Discussions: useDeferredValue

What?

useDeferredValue is a new hook in react which can be used to defer non-urgent updates triggered by some action like a state update.

useDeferredValue hook accepts a value and returns a new copy of the value that will defer to more urgent updates. If react is busy, like rendering an urgent update, the return value will be the previous value and once the urgent update is completed, you will get the updated value from the hook.

import { useState, useEffect, useDeferredValue } from "react";

function App({data}) {
    const [query, setQuery] = useState("");
    const [result, setResult] = useState(data);

    // Showing result is non-urgent update
    const deferredQuery = useDeferredValue(query);

  useEffect(() => {
      const searchResult = search(data, deferredQuery);
      setResult(searchResult);
  }, [deferredQuery]);

  return (
    <div className="App">
      <label htmlFor="search users">Search: </label>
      <input
        type="search"
        value={query}
        onChange={(e) => setQuery(e.target.value)} // urgent update
      />

        <DataView data={result}/>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Here search will be performed on the deferred query and show the search result is a non-urgent update. But showing what the user typed in the input field is an urgent update. Let's go in deep,

Let's say you entered the search query "toy",

In React 17 or before,

  1. On "t", update the state of the input to "t", perform a search for "t" and update the state to show results.
  2. On "o", update the state of the input to "to", perform a search for "to" and update the state to show results.
  3. On "y", update the state of the input to "toy", perform a search for "toy" and update the state to show results.

In React 18: using useDeferredValue,

  1. On "t", update the state of the input to "t" and since there is an urgent update pending (user typed "o", need to update input state), useDeferredValue hook return old value "", so no search performed.
  2. On "o", update the state of the input to "to" and since there is an urgent update pending (user typed "y", need to update input state), useDeferredValue hook return old value "", so no search performed.
  3. On "y", update the state of the input to "toy" and since there is no urgent update pending useDeferredValue hook returns new value "toy" and the search will be performed and ui will show search results.

This hook is similar to a debouncing hook like useDebounce but the benefit of using useDeferredValue is that React will work on the update as soon as other work finishes (instead of waiting for an arbitrary amount of time).

So if you use the useDeferredValue hook, in high-end machines the non-urgent updates will be faster than in low-end machines since high-end machines can process updates quickly. But in the case of useDebounce, the delay for a non-urgent update will be the same in both cases and hence we won't be able to leverage the full resources available.

Why?

We can create a better user experience if have an option to tell react which update is urgent and which is non-urgent since we will have more control over the UI updates.

How to use?

Upgrade to react 18, and use the useDeferredValue hook.

Example:
With useDeferredValue: https://codesandbox.io/s/react-18-usedeferredvalue-s4lgn2
Without useDeferredValue: https://codesandbox.io/s/react-18-no-usedeferredvalue-wvel7c

Try enabling CPU throttling to see the difference
CPU throttling in browser-useDeferredValue-react18

Top comments (0)