export default async function UserProfile({ userId }) { const user = await fetch(`https://api.example.com/users/${userId}`).then(res => res.json()); return <div>{user.name}</div>; }
Server Components re-render when their props change, triggering new data fetching and rendering on the server. Client-side state changes or UI interactions inside the component do not cause server re-renders. CSS changes affect styling but do not trigger re-renders.
export default function Page() { return <ClientCounter />; } 'use client'; import { useState } from 'react'; function ClientCounter() { const [count, setCount] = useState(0); return <button onClick={() => setCount(count + 1)}>Count: {count}</button>; }
Client Components can use React hooks like useState to update UI immediately on the client side. The button text updates without a full page reload. Server Components do not handle client state.
Using cache: 'no-store' tells Next.js to fetch fresh data on every request, disabling caching and enabling dynamic rendering. Other options either cache or reload cached data.
import { useSearchParams } from 'next/navigation'; export default function Page() { const searchParams = useSearchParams(); const filter = searchParams.get('filter'); return <div>Filter: {filter}</div>; }
useSearchParams is a client-side hook and cannot be used inside Server Components. Using it there causes the component not to update on URL changes. To react to URL changes in Server Components, use props or params passed from the router.
Using Server Components with fetch cache set to 'no-store' fetches fresh data on every request. Static layouts remain cached, so only dynamic parts re-render. Client Components fetch on client side, losing server benefits. getStaticProps and getServerSideProps are from Pages Router, not App Router.