</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.

To make it more obvious to the user, you can add a visual indication when the
stale result list is displayed:

    
    
    <div style={{  
    
    
      opacity: query !== deferredQuery ? 0.5 : 1   
    
    
    }}>  
    
    
      <SearchResults query={deferredQuery} />  
    
    
    </div>

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 dimmed 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);
      const isStale = query !== deferredQuery;
      return (
        <>
          <label>
            Search albums:
            <input value={query} onChange={e => setQuery(e.target.value)} />
          </label>
          <Suspense fallback={<h2>Loading...</h2>}>
            <div style={{ opacity: isStale ? 0.5 : 1 }}>
              <SearchResults query={deferredQuery} />
            </div>
          </Suspense>
        </>
      );
    }
    
    

Show more

###  Note

Both deferred values and  Transitions  let you avoid showing Suspense fallback
in favor of inline indicators. Transitions mark the whole update as non-urgent
so they are typically used by frameworks and router libraries for navigation.
Deferred values, on the other hand, are mostly useful in application code
where you want to mark a part of UI as non-urgent and let it “lag behind” the
rest of the UI.

* * *

###  Preventing already revealed content from hiding

When a component suspends, the closest parent Suspense boundary switches to
showing the fallback. This can lead to a jarring user experience if it was
already displaying some content. Try pressing this button:

App.js  Layout.js  IndexPage.js  ArtistPage.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 IndexPage from './IndexPage.js';
    import ArtistPage from './ArtistPage.js';
    import Layout from './Layout.js';
    
    export default function App() {
      return (
        <Suspense fallback={<BigSpinner />}>
          <Router />
        </Suspense>
      );
    }
    
    function Router() {
      const [page, setPage] = useState('/');
    
      function navigate(url) {
        setPage(url);
      }
    
      let content;
      if (page === '/') {
        content = (
          <IndexPage navigate={navigate} />
        );
      } else if (page === '/the-beatles') {
        content = (
          <ArtistPage
            artist={{
              id: 'the-beatles',
              name: 'The Beatles',
            }}
          />
        );
      }
      return (
        <Layout>
          {content}
        </Layout>
      );
    }
    
    function BigSpinner() {
      return <h2>🌀 Loading...</h2>;
    }
    
    

Show more

When you pressed the button, the ` Router ` component rendered ` ArtistPage `
instead of ` IndexPage ` . A component inside ` ArtistPage ` suspended, so the
closest Suspense boundary started showing the fallback. The closest Suspense
boundary was near the root, so the whole site layout got replaced by `
BigSpinner ` .

To prevent this, you can mark the navigation state update as a _