Next.js
Beginner
1 min read
The use client Directive and Client Component Patterns
Example
// Wrapping a third-party component that lacks 'use client'
// components/providers/ThemeProvider.tsx
'use client';
// next-themes doesn't always ship with 'use client', so we wrap it
export { ThemeProvider } from 'next-themes';
// app/layout.tsx — using the wrapped provider
import { ThemeProvider } from '@/components/providers/ThemeProvider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
{/* ThemeProvider is Client but wraps Server Component children */}
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</body>
</html>
);
}
// Passing Server Component as children to Client Component
// components/Modal.tsx
'use client';
import { useState } from 'react';
export default function Modal({ children }: { children: React.ReactNode }) {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open</button>
{open && (
<div className="modal-overlay">
<div className="modal-content">
<button onClick={() => setOpen(false)}>Close</button>
{/* children can be a Server Component rendered result */}
{children}
</div>
</div>
)}
</>
);
}