Dynamic rendering triggers let your Next.js app update pages automatically when data changes or user actions happen. This keeps the page fresh without needing a full reload.
Dynamic rendering triggers in NextJS
Start learning this pattern below
Jump into concepts and practice - no test required
import { useState, useEffect } from 'react'; export default function Page() { const [data, setData] = useState(null); useEffect(() => { async function fetchData() { const res = await fetch('/api/data'); const json = await res.json(); setData(json); } fetchData(); }, []); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; }
Use useState to hold data that changes.
Use useEffect to run code when the component loads or when dependencies change.
import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Count: {count} </button> ); }
import { useEffect, useState } from 'react'; export default function DataFetcher() { const [data, setData] = useState(null); useEffect(() => { fetch('/api/data') .then(res => res.json()) .then(json => setData(json)); }, []); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; }
This component shows a new random number every second. It uses setInterval inside useEffect to update state regularly, triggering dynamic rendering.
The aria-live="polite" attribute helps screen readers announce changes politely.
import { useState, useEffect } from 'react'; export default function RandomNumber() { const [number, setNumber] = useState(null); useEffect(() => { const interval = setInterval(() => { setNumber(Math.floor(Math.random() * 100)); }, 1000); return () => clearInterval(interval); }, []); return ( <main aria-live="polite" style={{ fontSize: '2rem', textAlign: 'center', marginTop: '2rem' }}> {number === null ? 'Generating number...' : `Random number: ${number}`} </main> ); }
Remember to clean up intervals or subscriptions in useEffect to avoid memory leaks.
Use aria-live regions to improve accessibility when content updates dynamically.
Dynamic rendering helps keep your app interactive and responsive to user actions or data changes.
Dynamic rendering triggers update your page automatically when data or state changes.
Use React hooks like useState and useEffect to manage dynamic updates.
Always consider accessibility and cleanup when using dynamic rendering.
Practice
Solution
Step 1: Understand the purpose of
useStateuseStatecreates a state variable that, when updated, triggers a re-render of the component.Step 2: Compare with other hooks
useEffectruns side effects but does not itself trigger re-renders;useRefholds mutable values without causing re-renders;useContextshares data but depends on context changes.Final Answer:
useState-> Option CQuick Check:
State change triggers re-render = useState [OK]
- Confusing useEffect as a trigger for re-render
- Using useRef expecting re-render on change
- Thinking useContext alone triggers re-render
useState?Solution
Step 1: Review correct useState syntax
useState returns an array with current state and a setter function. The setter function is called with the new value to update state.Step 2: Identify correct setter usage
OnlysetCount(5);correctly calls the setter function. Assigning directly tosetCountorcountis invalid.Final Answer:
const [count, setCount] = useState(0); setCount(5); -> Option BQuick Check:
Call setter function with new value = setCount(5) [OK]
- Assigning value directly to setter function
- Trying to call state variable as a function
- Ignoring array destructuring from useState
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<>
Count: {count}
setCount(count + 1)}>Increment
</>
);
}Solution
Step 1: Understand initial state and button action
Initial count is 0. Each button click callssetCount(count + 1), increasing count by 1.Step 2: Calculate count after two clicks
After first click: count = 1; after second click: count = 2.Final Answer:
Count: 2 -> Option AQuick Check:
Increment twice from 0 = 2 [OK]
- Assuming state does not update immediately
- Confusing initial value with updated value
- Expecting NaN due to wrong state usage
import { useState } from 'react';
export default function Example() {
const [value, setValue] = useState('');
function handleClick() {
value = 'Updated';
}
return (
<>
{value}
Update
</>
);
}Solution
Step 1: Check how state is updated
The functionhandleClickassigns directly tovalue, which is a state variable and read-only.Step 2: Correct way to update state
State must be updated by calling the setter functionsetValue('Updated')to trigger re-render.Final Answer:
Directly assigning to state variable instead of using setter -> Option DQuick Check:
Use setter function to update state [OK]
- Assigning state variable directly
- Forgetting to call setter function
- Confusing state variable with setter
import { useState, useEffect } from 'react';
export default function UserProfile() {
const [user, setUser] = useState(null);
useEffect(() => {
let isMounted = true;
fetch('/api/user')
.then(res => res.json())
.then(data => {
if (isMounted) setUser(data);
});
return () => { isMounted = false; };
}, []);
if (!user) return <p>Loading...</p>;
return <p>Hello, {user.name}!</p>;
}Solution
Step 1: Analyze data fetching inside useEffect
Fetching data insideuseEffectwith empty dependency array runs once on mount, triggering dynamic rendering when data arrives.Step 2: Understand cleanup with isMounted flag
TheisMountedflag prevents setting state if the component unmounts before fetch completes, avoiding memory leaks or errors.Final Answer:
Correct: fetch in useEffect with cleanup flag to avoid setting state after unmount -> Option AQuick Check:
Fetch in useEffect + cleanup = safe dynamic update [OK]
- Fetching data outside useEffect causing repeated renders
- Not cleaning up async calls causing memory leaks
- Missing dependency array causing multiple fetches
