pense component.**
They include:

  * 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)

Suspense **does not** detect when data is fetched inside an Effect or event
handler.

The exact way you would load data in the ` Albums ` component above depends on
your framework. If you use a Suspense-enabled framework, you’ll find the
details in its data fetching documentation.

Suspense-enabled data fetching without the use of an opinionated framework is
not yet supported. The requirements for implementing a Suspense-enabled data
source are unstable and undocumented. An official API for integrating data
sources with Suspense will be released in a future version of React.

* * *

###  Revealing content together at once

By default, the whole tree inside Suspense is treated as a single unit. For
example, even if _only one_ of these components suspends waiting for some
data, _all_ of them together will be replaced by the loading indicator:

    
    
    <Suspense fallback={<Loading />}>  
    
    
      <Biography />  
    
    
      <Panel>  
    
    
        <Albums />  
    
    
      </Panel>  
    
    
    </Suspense>

Then, after all of them are ready to be displayed, they will all appear
together at once.

In the example below, both ` Biography ` and ` Albums ` fetch some data.
However, because they are grouped under a single Suspense boundary, these
components always “pop in” together at the same time.

ArtistPage.js  Panel.js

ArtistPage.js

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

    
    
    import { Suspense } from 'react';
    import Albums from './Albums.js';
    import Biography from './Biography.js';
    import Panel from './Panel.js';
    
    export default function ArtistPage({ artist }) {
      return (
        <>
          <h1>{artist.name}</h1>
          <Suspense fallback={<Loading />}>
            <Biography artistId={artist.id} />
            <Panel>
              <Albums artistId={artist.id} />
            </Panel>
          </Suspense>
        </>
      );
    }
    
    function Loading() {
      return <h2>🌀 Loading...</h2>;
    }
    
    

Show more

Components that load data don’t have to be direct children of the Suspense
boundary. For example, you can move ` Biography ` and ` Albums ` into a new `
Details ` component. This doesn’t change the behavior. ` Biography ` and `
Albums ` share the same closest parent Suspense boundary, so their reveal is
coordinated together.

    
    
    <Suspense fallback={<Loading />}>  
    
    
      <Details artistId={artist.id} />  
    
    
    </Suspense>  
    
    
      
    
    
    function Details({ artistId }) {  
    
    
      return (  
    
    
        <>  
    
    
          <Biography artistId={artistId} />  
    
    
          <Panel>  
    
    
            <Albums artistId={artistId} />  
    
    
          </Panel>  
    
    
        </>  
    
    
      );  
    
    
    }

* * *

###  Revealing nested content as it loads

When a component suspends, the closest parent Suspense component shows the
fallback. This lets you nest multiple Suspense components to create a loading
sequence. Each Suspense boundary’s fallback will be filled in as the next
level of content becomes available. For example, you can give the album list
its own fallback:

    
    
    <Suspense fallback={<BigSpinner />}>  
    
    
      <Biography />  
    
    
      <Suspense fallback={<AlbumsGlimmer />}>  
    
    
        <Panel>  
    
    
          <Albums />  
    
    
        </Panel>  
    
    
      </Suspense>  
    
    
    </Suspense>

With this change, displaying the `