Building the Compound Child Components
Explore how to build compound child components in React with hooks and context. Understand how to create expandable components with Header, Body, and Icon child components that consume shared state, allowing you to manage UI behavior cleanly and efficiently.
Child Components of Expandable
There are three child components for the Expandable component.
These child components need to consume values from the context object created in Expandable.js.
To make this possible, we’ll do a little refactoring as shown below:
We export the context object, ExpandableContext, from Expandable.js.
Now, we may use the useContext hook to consume the values from the Provider.
The Header Child
Below is the Header child component fully implemented.
Simple, right?
It renders a div whose onClick callback is the toggle function for toggling the expanded state within the Expandable parent component.
The Body Child
Here’s the implementation for the Body child component:
Pretty simple as well.
The expanded value is retrieved from the context object and used within the rendered markup. Line 7 reads like this: expanded, render children, otherwise, render nothing.
The Icon Child
The Icon component is just as simple.
It renders either + or - depending on the value of expanded retrieved from the context object.
With all child components built, we can set them as Expandable properties. See below:
import Header from './Header'import Icon from './Icon'import Body from './Body'...const Expandable = ({ children, onExpand }) => {...}// Remember this is just a personal reference. It's not mandatoryExpandable.Header = HeaderExpandable.Body = BodyExpandable.Icon = Icon
Using the Expandable Component
Now, we can go ahead and use the Expandable component as designed:
<Expandable><Expandable.Header>React hooks</Expandable.Header><Expandable.Icon /><Expandable.Body>Hooks are awesome</Expandable.Body></Expandable>
Current Look
Here is the Expandable component so far!
// Body.js
import { useContext } from 'react'
import { ExpandableContext } from './Expandable'
const Body = ({ children }) => {
const { expanded } = useContext(ExpandableContext)
return expanded ? children : null
}
export default BodyQuick Quiz!
Select all that apply for this question.
Why do we export the ExpandableContext from Expandable.js? Multi-select
The child components of Expandable need to consume values from the context object created in Expandable.js.
Because the user’s app needs to use the values in that context
The context cannot be used elsewhere without the export
This works but it has to be the ugliest component I’ve ever seen. We can do better. Let’s try in the next lesson!