Skip to content

[Autocomplete] Compound component exploration #1794

@dleroux

Description

@dleroux

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 children therefore 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions