What is a compound component?#
You can think of compound components as groups of components which cannot live without each other, such as the select and option elements in HTML. They will always have the following characteristics:
-
a parent component with nested child components
-
the parent component shares state implicitly with its child components
How do you implement a compound component?#
You first create a root component which wraps its children in a context provider. Via the value prop, the root component can share state and ways to manipulate that state with its children. Via use the child components can consume the state and ways to manipulate that state provided by the parent and act accordingly.
React 16 (class component) approach vs React 19 (functional component) approach#
A previous blog post of mine showed a way the compound component pattern was implemented in the days of React 16. At that time, class components were in full swing.
The way for a root component to implicitly share state and functionality with its children was for the root component to map its children to clones of themselves. The clones would receive the parent's state and functionality via their props.
What is no longer being used in the React 19 version?#
-
React.cloneElement- We do not need to clone the children to make sure they have access to the parent's state. Instead the children will grab the state from the parent directly with theuseAPI. -
React.Children.map- As mentioned above, we do not need to map through the children to make clones which receive parent state and functionality. Instead the children will grab global state directly from the parent via theuseAPI.
A note on adding child components to the root component via static properties#
Sometimes the child components are pinned directly to the parent component via static props.
Toggle.On = ({ on, children }) => on && children;Toggle.Off = ({ on, children }) => !on && children;Toggle.Button = ({ on, toggle }) => <button onClick={toggle}> Toggle </button>;An advantage of doing this is that only Toggle needs to be imported and the allowed children come along for the ride. The React 19 allows for any children - not just the "allowed" ones which receive state from the provider.