React useDefferedValue

Dead Simple Chat Team

Table of Contents

useDeferredValue lets you defer updating a part of the UI

const deferredValue = useDeferredValue(value)

useDeferredValue is react hook. You can call this hook at the top of your component to get a deferred version of the value.

import { useState, useDeferredValue } from 'react';

function SearchPage() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  // ...
}

Parameters

  • value: the value you want to defer. It can have any type

Returns

During the inital render the first value rendered will be the one that you provided.

During updates react will render the old value provided and then try to re render the new value in the as it becomes available.

Caveats

  • useDeferredValue accepts primitive values like Strings and numbers or Objects that are created outside of rendering
  • If you create new Object during the rendering and pass it to useDeferredValue, it may be different on every re render
  • useDeferred value is integrated with suspense. the user will see the old deferred value untill the data loads. User will not see the fallback value if a new background update suspends the UI
  • Any updates caused by events like typing are prioritized over the background-re render. There is no fixed delay caused by useDeferredValue As soon as react finishes the old render, it will start working on the beackground re render with new deferred value
  • useDeferredValue does not itself prevent extra network requests
  • The backgroud re render caused by useDeferredValue does not fire Effects untill it is committed to the screen
  • If the background ┬áre render suspends its effects will fire after the UI updates

How to use useDeferred value

The main utility of useDeferred value is to show stale content while the new content is loading

Here is how you can use useDeferredValue

call the hook on top of your component

import { useState, useDeferredValue } from 'react';

function SearchPage() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  // ...
}

we have already explained how the useDeferred value works but I will do it again

When the initial render occurs the deferred value is the value that you provided but

in subsequent renders the deferred value will be the old value and then react will try to re render the new value in the background.

example:

Note before starting the example

  • In this example we assume that the app uses one of the Suspense-enabled data sources
  • Lazy-loading the components we lazy

In this example we have a component named SearchResults which suspends when getting search results from the database

import { Suspense, useState } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>fetching...</h2>}>
        <SearchResults query={query} />
      </Suspense>
    </>
  );
}

A common pattern is to keep showing the older results until new results are available to show

We can call useDeferredValue to pass a deferred version of the query down

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  return (
    <>
      <label>
        Search all albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>fetching...</h2>}>
        <SearchResults query={deferredQuery} />
      </Suspense>
    </>
  );
}

the query will update immediately so the input will display the new value.

deferredQuery will keep its previous value until the data has loaded, So SearchResults will show the stale results for a bit

Enter "a" in the example and wait for the results to load and then edit the input to "ab"

Instead of the Suspense fallback we will see the old result until the new results are loaded

import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <SearchResults query={deferredQuery} />
      </Suspense>
    </>
  );
}

Indicating that the content is stale

there is no indication that the result list for the latest query is still loading. This could be confusing to the user if the results take some time to load. We can add a visual indication when the old result is still displayed.

Conclusion

In this article we have explained how to use useDeferredValue with examples

Thanks for reading the article