Skip to content

Commit

Permalink
Add Compound Components section to components CONTRIBUTING.md (#34697)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegohaz authored Sep 11, 2021
1 parent a84c037 commit 3703b46
Showing 1 changed file with 55 additions and 3 deletions.
58 changes: 55 additions & 3 deletions packages/components/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,64 @@ function LinkButton( { href, children } ) {
return <Button variant="primary" as="a" href={href}>{ children }</Button>;
}
```
-->

### Composition patterns
#### Compound components

TBD — E.g. Using `children` vs custom render props vs arbitrary "data" props
When creating components that render a list of subcomponents, prefer to expose the API using the [Compound Components](https://kentcdodds.com/blog/compound-components-with-react-hooks) technique over array props like `items` or `options`:

### (Semi-)Controlled components
```jsx
// ❌ Don't:
<List
items={ [
{ value: 'Item 1' },
{ value: 'Item 2' },
{ value: 'Item 3' },
] }
/>
```
```jsx
// ✅ Do:
<List>
<ListItem value="Item 1" />
<ListItem value="Item 2" />
<ListItem value="Item 3" />
</List>
```

When implementing this pattern, avoid using `React.Children.map` and `React.cloneElement` to map through the children and augment them. Instead, use React Context to provide state to subcomponents and connect them:

```jsx
// ❌ Don't:
function List ( props ) {
const [ state, setState ] = useState();
return (
<div { ...props }>
{ Children.map( props.children, ( child ) => cloneElement( child, { state } ) ) ) }
</div>
);
}
```
```jsx
// ✅ Do:
const ListContext = createContext();

function List( props ) {
const [ state, setState ] = useState();
return (
<ListContext.Provider value={ state }>
<div { ...props } />
</ListContext.Provider>
);
}

function ListItem( props ) {
const state = useContext( ListContext );
...
}
```

<!-- ### (Semi-)Controlled components
TBD
Expand Down

0 comments on commit 3703b46

Please sign in to comment.