All quizzesMedium
Compound & HOC — Series 2
Preview — 3 of 10 questions
Compared to the React.cloneElement-based compound component pattern (injecting props into direct children), what specific limitation does this Context-based version fix?
javascript
const AccordionContext = createContext(null);
function Accordion({ children }) {
const [openIndex, setOpenIndex] = useState(null);
return (
<AccordionContext.Provider value={{ openIndex, setOpenIndex }}>
{children}
</AccordionContext.Provider>
);
}
function AccordionItem({ index, title, children }) {
const { openIndex, setOpenIndex } = useContext(AccordionContext);
const isOpen = openIndex === index;
return (
<div>
<button onClick={() => setOpenIndex(isOpen ? null : index)}>{title}</button>
{isOpen && <div>{children}</div>}
</div>
);
}
// Usage — AccordionItem can be nested inside a wrapper div, unlike cloneElement-based compound components:
<Accordion>
<div className="styled-wrapper">
<AccordionItem index={0} title="Section 1">Content</AccordionItem>
</div>
</Accordion>AAccordionItem no longer needs to be a direct child of Accordion — since it reads shared state via useContext rather than receiving it as injected props from a parent that maps over its direct children, AccordionItem can be nested arbitrarily deep inside other wrapping elements (like the styled-wrapper div above) and still work correctly, which the cloneElement-based version specifically couldn't support
BThis version eliminates the need for Accordion to hold any state at all — AccordionItem manages everything independently
CContext-based compound components can only have a single AccordionItem at a time — multiple open sections are not supported by this pattern
DThis pattern requires class components — useContext cannot be called from AccordionItem if it's a function component
Auth, theme, and query-caching are each wrapped as their own Provider, nested around the whole app. What makes this Provider pattern a good fit specifically for concerns like these, as opposed to passing them down as regular props?
javascript
function App() {
return (
<AuthProvider>
<ThemeProvider>
<QueryClientProvider>
<Router />
</QueryClientProvider>
</ThemeProvider>
</AuthProvider>
);
}AProviders are required by React for any state used in more than one component — regular props cannot be shared between siblings under any circumstances
BThis pattern only works for exactly three providers — a fourth would exceed a hard limit on nested Context providers
CAuth, theme, and query-caching are all genuinely "cross-cutting" — needed by many components scattered at many different, unpredictable depths throughout the entire app (a deeply nested button might need theme colors; a form five levels down might need auth status) — Provider-based Context lets any of those components access what they need directly, without every single intermediate component in between needing to know about or forward props it doesn't otherwise care about, which is exactly the scenario prop drilling handles poorly
DNesting providers in this way automatically merges all three into a single combined context object, improving performance
What does the as prop pattern let Text do that a version hardcoding <p>{children}</p> couldn't?
javascript
function Text({ as: Component = 'p', children, ...rest }) {
return <Component {...rest}>{children}</Component>;
}
// Usage:
<Text>Default paragraph</Text>
<Text as="h1">Rendered as an h1 instead</Text>
<Text as={Link} to="/profile">Rendered as a custom Link component</Text>Aas is required by React for any component accepting a children prop — this isn't an optional pattern
BText's styling/behavior logic (whatever it does beyond just rendering children) is decoupled from which underlying element or component actually renders — the same Text component can render as a <p>, an <h1>, or even an entirely different custom component (like a routing Link), letting one reusable component serve many different structural/semantic needs without maintaining separate near-duplicate components for each possible underlying tag
Cas can only ever be set to a plain HTML tag name string — passing a custom component reference like Link is not supported
DThis pattern eliminates the need for the ...rest spread entirely, since as automatically forwards all props on its own
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.