spense-enabled data source:

  * Data fetching with Suspense-enabled frameworks like [ Relay ](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [ Next.js ](https://nextjs.org/docs/getting-started/react-essentials)
  * Lazy-loading component code with [ ` lazy ` ](/reference/react/lazy)
  * Reading the value of a Promise with [ ` use ` ](/reference/react/use)

[ Learn more about Suspense and its limitations. ](/reference/react/Suspense)

In this example, the ` SearchResults ` component [ suspends
](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading)
while fetching the search results. Try typing ` "a" ` , waiting for the
results, and then editing it to ` "ab" ` . The results for ` "a" ` get
replaced by the loading fallback.

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    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>Loading...</h2>}>
            <SearchResults query={query} />
          </Suspense>
        </>
      );
    }
    
    

Show more

A common alternative UI pattern is to _defer_ updating the list of results and
to keep showing the previous results until the new results are ready. 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 albums:  
    
    
            <input value={query} onChange={e => setQuery(e.target.value)} />  
    
    
          </label>  
    
    
          <Suspense fallback={<h2>Loading...</h2>}>  
    
    
            <SearchResults query={deferredQuery} />  
    
    
          </Suspense>  
    
    
        </>  
    
    
      );  
    
    
    }

The ` query ` will update immediately, so the input will display the new
value. However, the ` 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 below, wait for the results to load, and then
edit the input to ` "ab" ` . Notice how instead of the Suspense fallback, you
now see the stale result list until the new results have loaded:

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    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>
        </>
      );
    }
    
    

Show more

#####  Deep Dive

####  How does deferring a value work under the hood?

Show Details

You can think of it as happening in two steps:

  1. **First, React re-renders with the new` query ` ( ` "ab" ` ) but with the old ` deferredQuery ` (still ` "a") ` . ** The ` deferredQuery ` value, which you pass to the result list, is _deferred:_ it “lags behind” the ` query ` value. 

  2. **In the background, React tries to re-render with _both_ ` query ` and ` deferredQuery ` updated to ` "ab" ` . ** If