-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Compound components offer a more HTML-like approach to building other components. We seldom use them in our codebase today. With the need to make our components more flexible and the recent updates to the context API, there is an opportunity for us to make use of new patterns that will help us get closer to our goal.
During the exploration of the Autocomplete project I have explored various ways and approaches to building components:
- Using the
cloneElement - Using a prop for the text field and context for the list box
- Using the parent context to control and render children
cloneElement
React’s top-level API provides us the ability to create new components using an existing component as a starting point via cloneElement. To take advantage of this feature with compound components, we loop through the children, verify their type, clone them and include whatever mark-up or props we need.
Pros
- The developer has full control over the rendering of the children.
- We never render
childrentherefore components that aren’t meant as children are ignored. - The element being cloned can be extended with additional props and refs
- Rendering is isolated only to the individual list items or the Textfield
Cons
- Increases memory footprint
- Requires children to be immediate children of a parent
- In functional components, their elements are cloned as every render.
- Difficult to type
Using a combination of a Texfield Prop Context API
React’s Context API allows us to share values between components in a tree without having to explicitly pass them through props. With the Autocomplete, we use Context to build our List Box components allowing in to render in place as a child. There is actually very little use of context in the prototype because of the limited features but I can envision growing as we develop the component.
The Textfield is passed in a prop in this particular because we needed more flexibility with the resulting markup.
Pros
- Context can be created at every level of the tree: The list can manage it’s own context while communicating with the Autocompletes context. This makes components very portable.
- Rendering is isolated only to the individual list items or the Textfield.
Cons
- We render the children, regardless of their type.
- Rendering the composed list as a child and the Textfield as a prop feels arbitrary/not intuitive
Using The Parent’s Context to Render Children
This approach makes use of the Context API but instead of rendering children directly in the component, the children component calls a method on Context that results in the parent component rendering the required mark-up. We currently use this approach to render Toast within own frame component.
Pros
- Full control over the rendering of the children
Cons
- Feels like an anti-pattern, children need to render within the Context provider, but then render in the parent component instead.
- The {children} render nothing other than the text field, and then used as the popover activator
- Re-renders every time and option is added