Compound Component Pattern
Build flexible compound components using React Context for implicit parent-child communication.
import { createContext, useContext, useState, ReactNode } from 'react';
interface AccordionContext {
openId: string | null;
toggle: (id: string) => void;
}
const Ctx = createContext<AccordionContext | null>(null);
const useAccordion = () => {
const ctx = useContext(Ctx);
if (!ctx) throw new Error('Must be used within Accordion');
return ctx;
};
export function Accordion({ children }: { children: ReactNode }) {
const [openId, setOpenId] = useState<string | null>(null);
const toggle = (id: string) => setOpenId((prev) => (prev === id ? null : id));
return <Ctx.Provider value={{ openId, toggle }}>{children}</Ctx.Provider>;
}
Accordion.Item = function Item({ id, title, children }: { id: string; title: string; children: ReactNode }) {
const { openId, toggle } = useAccordion();
return (
<div>
<button onClick={() => toggle(id)}>{title}</button>
{openId === id && <div>{children}</div>}
</div>
);
};Use Cases
- Accordion components
- Tab interfaces
- Dropdown menus
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
Render Prop Pattern
Share stateful logic between components using the render prop pattern for maximum flexibility.
Context + useReducer State Management
Type-safe global state pattern combining React Context with useReducer for complex state without external libs.
Multi-Zone Application Setup
Compose multiple Next.js apps under one domain using rewrites for micro-frontend architecture.
useFetch — Generic Data Fetching Hook
Custom React hook for data fetching with loading, error, and refetch states using the Fetch API.