Bird
Raised Fist0
NextJSframework~20 mins

Streaming with Suspense in NextJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Streaming Suspense Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What is the output of this streaming Suspense component?

Consider this Next.js component using Suspense and streaming. What will the user see first when this component renders?

NextJS
import React, { Suspense } from 'react';

function SlowComponent() {
  const data = new Promise(resolve => setTimeout(() => resolve('Loaded Data'), 3000));
  const text = React.use(data);
  return <div>{text}</div>;
}

export default function Page() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <SlowComponent />
    </Suspense>
  );
}
AThe user sees 'Loading...' immediately, then after 3 seconds sees 'Loaded Data'.
BThe user sees 'Loaded Data' immediately without delay.
CThe user sees a blank page for 3 seconds, then 'Loaded Data' appears.
DThe user sees an error because Suspense cannot be used with promises.
Attempts:
2 left
💡 Hint

Think about what Suspense does when waiting for data.

state_output
intermediate
2:00remaining
What is the final rendered output after streaming completes?

Given this Next.js streaming Suspense example, what is the final rendered HTML content?

NextJS
import React, { Suspense } from 'react';

function Data() {
  const promise = new Promise(resolve => setTimeout(() => resolve('Hello from server'), 2000));
  const message = React.use(promise);
  return <p>{message}</p>;
}

export default function Page() {
  return (
    <Suspense fallback={<p>Loading message...</p>}>
      <Data />
    </Suspense>
  );
}
A<p>Hello from server</p> immediately
B<p>Loading message...</p> followed by <p>Hello from server</p>
C<p>Loading message...</p> only, never replaced
DAn error is thrown because React.use cannot be used with promises
Attempts:
2 left
💡 Hint

Remember how Suspense fallback works with async data.

🔧 Debug
advanced
2:00remaining
Why does this streaming Suspense component cause a runtime error?

Examine this Next.js component using Suspense and streaming. Why does it cause a runtime error?

NextJS
import React, { Suspense } from 'react';

function BrokenComponent() {
  const data = fetch('/api/data').then(res => res.json());
  const result = React.use(data);
  return <div>{result.value}</div>;
}

export default function Page() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <BrokenComponent />
    </Suspense>
  );
}
AReact.use cannot be used with promises returned by fetch directly.
BThe Suspense fallback is missing, causing the error.
CThe fetch call is not awaited, so result is undefined.
DThe component is missing a key prop inside Suspense.
Attempts:
2 left
💡 Hint

Consider how React.use works with promises and what it expects.

🧠 Conceptual
advanced
2:00remaining
Which statement about streaming with Suspense in Next.js is true?

Choose the correct statement about how streaming with Suspense works in Next.js.

AStreaming with Suspense only works on client-side rendering, not server-side.
BStreaming with Suspense disables fallback UI rendering.
CStreaming with Suspense requires disabling React Server Components.
DStreaming with Suspense allows parts of the UI to render immediately while waiting for async data in other parts.
Attempts:
2 left
💡 Hint

Think about how Suspense helps with loading states and partial rendering.

📝 Syntax
expert
3:00remaining
Which option correctly implements streaming Suspense with async server component in Next.js?

Identify the correct code snippet that uses streaming Suspense with an async server component in Next.js 14+.

A
export default async function Page() {
  const data = await fetch('https://api.example.com/data').then(res =&gt; res.json());
  return &lt;div&gt;{data.message}&lt;/div&gt;;
}
B
import { Suspense } from 'react';

async function Data() {
  const data = fetch('https://api.example.com/data').then(res =&gt; res.json());
  return &lt;p&gt;{data.message}&lt;/p&gt;;
}

export default function Page() {
  return (
    &lt;Suspense fallback={&lt;p&gt;Loading...&lt;/p&gt;}&gt;
      &lt;Data /&gt;
    &lt;/Suspense&gt;
  );
}
C
import { Suspense } from 'react';

async function Data() {
  const data = await fetch('https://api.example.com/data').then(res =&gt; res.json());
  return &lt;p&gt;{data.message}&lt;/p&gt;;
}

export default function Page() {
  return (
    &lt;Suspense fallback={&lt;p&gt;Loading...&lt;/p&gt;}&gt;
      &lt;Data /&gt;
    &lt;/Suspense&gt;
  );
}
D
import { Suspense } from 'react';

function Data() {
  const data = fetch('https://api.example.com/data').then(res =&gt; res.json());
  const message = React.use(data);
  return &lt;p&gt;{message}&lt;/p&gt;;
}

export default function Page() {
  return (
    &lt;Suspense fallback={&lt;p&gt;Loading...&lt;/p&gt;}&gt;
      &lt;Data /&gt;
    &lt;/Suspense&gt;
  );
}
Attempts:
2 left
💡 Hint

Remember async components must be awaited and Suspense fallback is required for streaming.

Practice

(1/5)
1. What is the main purpose of using Suspense in Next.js streaming?
easy
A. To show a fallback UI while waiting for slow components to load
B. To prevent any component from rendering
C. To disable server-side rendering
D. To cache all components on the client

Solution

  1. Step 1: Understand Suspense role

    Suspense is used to wrap components that may take time to load, showing a fallback UI meanwhile.
  2. Step 2: Identify the purpose in streaming

    In streaming, it helps parts of the page appear quickly by showing placeholders until content is ready.
  3. Final Answer:

    To show a fallback UI while waiting for slow components to load -> Option A
  4. Quick Check:

    Suspense fallback = show UI while loading [OK]
Hint: Suspense shows fallback UI during loading [OK]
Common Mistakes:
  • Thinking Suspense stops rendering completely
  • Confusing Suspense with caching
  • Assuming Suspense disables server rendering
2. Which of the following is the correct way to use Suspense in a Next.js component?
easy
A. <Suspense><MyComponent fallback="Loading..." /></Suspense>
B. <Suspense fallback="<Loading />"><MyComponent />
C. <Suspense fallback="Loading..."><MyComponent /></Suspense>
D. <Suspense fallback="<Loading />"><MyComponent /></Suspense>

Solution

  1. Step 1: Check Suspense syntax

    The Suspense component requires a fallback prop with a React node, and must wrap the child component properly.
  2. Step 2: Identify correct JSX structure

    <Suspense fallback="Loading..."><MyComponent /></Suspense> correctly uses fallback="Loading..." and properly closes the Suspense tag.
  3. Final Answer:

    <Suspense fallback="Loading..."><MyComponent /></Suspense> -> Option C
  4. Quick Check:

    Suspense fallback prop + proper closing = correct syntax [OK]
Hint: Suspense needs fallback prop and closing tag [OK]
Common Mistakes:
  • Forgetting to close Suspense tag
  • Passing fallback inside child component
  • Using fallback as string with JSX tags
3. Given this Next.js component using streaming with Suspense:
import { Suspense } from 'react';

function SlowComponent() {
  return 
Data loaded
; } export default function Page() { return (
Loading...
}> ); }

What will the user see first when this page loads?
medium
A. An error because Suspense cannot be used here
B. The text 'Loading...' immediately, then 'Data loaded' after SlowComponent finishes
C. A blank page until SlowComponent loads
D. Only 'Data loaded' without any loading text

Solution

  1. Step 1: Check if SlowComponent suspends

    SlowComponent is synchronous and returns <div>Data loaded</div> immediately without throwing a promise, so Suspense does not trigger fallback.
  2. Step 2: Determine initial render behavior

    The entire page renders instantly with 'Data loaded' inside the div. No fallback appears because there is no suspension.
  3. Final Answer:

    Only 'Data loaded' without any loading text -> Option D
  4. Quick Check:

    No suspend = no fallback, direct content render [OK]
Hint: Suspense fallback only if children suspend (throw promise) [OK]
Common Mistakes:
  • Assuming Suspense always shows fallback
  • Thinking synchronous components trigger loading
  • Expecting streaming without suspend mechanism
4. Identify the error in this Next.js streaming code snippet:
import { Suspense } from 'react';

export default function Page() {
  return (
    <div>
      <Suspense fallback="Loading...">
        <SlowComponent />
      </Suspense>
    </div>
  );
}

function SlowComponent() {
  throw new Promise(resolve => setTimeout(resolve, 1000));
  return <div>Loaded</div>;
}
medium
A. The return statement after throw is unreachable
B. SlowComponent cannot throw a Promise
C. The fallback prop should be a React node, not a string
D. Suspense must be imported from 'next/suspense' not 'react'

Solution

  1. Step 1: Spot unreachable code

    The return <div>Loaded</div> after throw is unreachable because the throw executes first.
  2. Step 2: Validate other parts

    Import from 'react' is correct; throwing a Promise suspends correctly (though recreating it causes infinite loop here); fallback string is valid ReactNode.
  3. Final Answer:

    The return statement after throw is unreachable -> Option A
  4. Quick Check:

    throw before return = unreachable [OK]
Hint: Code after throw is unreachable [OK]
Common Mistakes:
  • Thinking fallback string causes issues
  • Believing components cannot throw Promises
  • Wrong import source for Suspense
5. You want to stream two slow components in Next.js with Suspense, showing their fallbacks independently. Which approach correctly achieves this?
hard
A. <Suspense fallback="Loading..."><ComponentA /></Suspense><ComponentB fallback="Loading B..." />
B. <Suspense fallback="Loading A..."><ComponentA /></Suspense><Suspense fallback="Loading B..."><ComponentB /></Suspense>
C. <ComponentA /><ComponentB /> without Suspense
D. <Suspense fallback="Loading A and B..."><ComponentA /><ComponentB /></Suspense>

Solution

  1. Step 1: Understand independent Suspense boundaries

    Wrapping each slow component in its own Suspense allows each to show its own fallback independently.
  2. Step 2: Analyze options

    <Suspense fallback="Loading A..."><ComponentA /></Suspense><Suspense fallback="Loading B..."><ComponentB /></Suspense> wraps each component separately with distinct fallbacks, enabling independent streaming. <Suspense fallback="Loading A and B..."><ComponentA /><ComponentB /></Suspense> shares one fallback for both, so they load together. <ComponentA /><ComponentB /> without Suspense has no fallback. <Suspense fallback="Loading..."><ComponentA /></Suspense><ComponentB fallback="Loading B..." /> incorrectly uses fallback on a component.
  3. Final Answer:

    <Suspense fallback="Loading A..."><ComponentA /></Suspense><Suspense fallback="Loading B..."><ComponentB /></Suspense> -> Option B
  4. Quick Check:

    Separate Suspense per component = independent fallbacks [OK]
Hint: Wrap each slow component in its own Suspense [OK]
Common Mistakes:
  • Using one Suspense for multiple components expecting separate fallbacks
  • Not wrapping slow components in Suspense
  • Passing fallback prop to child components