This site runs best with JavaScript enabled.

React Compound Components

Software Engineer, React Training, Testing JavaScript Training

There are situations when we need to pass props to multiple children components. Manually passing props makes app tightly coupled and less flexible. One solution is to use compound components.

Think of compound components like the <select> and <option> elements in HTML. Apart they don't do too much, but together they allow you to create the complete experience. — Vadim Nicolai

App.js

1import React from 'react'
2import {render} from 'react-dom'
3import {Radio} from 'antd'
4
5import './index.css'
6import 'antd/dist/antd.css'
7const bananas = require('./bananas.json')
8
9import List from './List'
10import Item from './Item'
11const RadioButton = Radio.Button
12const RadioGroup = Radio.Group
13
14export default class App extends React.Component {
15 state = {
16 items: bananas.bananas,
17 size: 'normal',
18 }
19
20 onChange = e => {
21 this.setState({size: e.target.value})
22 }
23
24 selectItem = title => () => this.setState({selectedItem: title})
25
26 render() {
27 const {items, size} = this.state
28 return (
29 <div>
30 <RadioGroup onChange={this.onChange} defaultValue="normal">
31 <RadioButton value="small">small</RadioButton>
32 <RadioButton value="normal">normal</RadioButton>
33 <RadioButton value="large">large</RadioButton>
34 </RadioGroup>
35 <List size={size} selectItem={this.selectItem}>
36 {items.map(({id, title}) => (
37 <Item key={id} title={title} />
38 ))}
39 </List>
40 {selectedItem}
41 </div>
42 )
43 }
44}
45
46render(<App />, document.getElementById('root'))

List.js

1import React from 'react'
2
3const List = ({size, children, selectItem}) => {
4 const listChildren = React.Children.map(children, child => {
5 return React.cloneElement(child, {size, selectItem})
6 })
7 return <ul>{listChildren}</ul>
8}
9
10export default List

Item.js

1import React from 'react'
2
3const styles = {
4 small: {
5 fontSize: '12px',
6 },
7 medium: {
8 fontSize: '14px',
9 },
10 large: {
11 fontSize: '16px',
12 },
13}
14
15const Item = ({title, size, selectItem}) => (
16 <li style={styles[size]} onClick={selectItem(title)}>
17 {title}
18 </li>
19)
20
21export default Item

Codesanbox example here Edit React List Drag & Drop - Javascript Example 1

Vadim Nicolai

Vadim Nicolai is a JavaScript software engineer.