ReactJS components with namespace

Imagine we want a pattern where the children components can be composed in any order. But the children components cannot be used unless they exists in a very specific parent component.

We can apply a name-spaced pattern to achieve this desire.

Imagine we have a Burger component where the burger ingredients can be ordered in any order. The burger ingredients might not make sense to be used unless they exist inside a Burger component.

This is an example of a React component with a namespace.

<Burger title="my burger">
<Burger.Bun />
<Burger.Meat />
<Burger.Bun />
</Burger>

From the naming the intent is clear. The Burger.Bun looks like a sub-component of a Burger component. The items can be in any order, but they should exists inside a Burger component.

A name-spaced component can easily be created by adding a component field to the parent component.

const Burger = ({children}) => <div>{children}</div>;
const Bun = () => <div> Bun </div>;
Burger.Bun = Bun;

The field can also be a class component if the state is needed.

const Burger = ({children}) => <div>{children}</div>;
Burger.Bun = class Bun extends React.Component {
state = {
name: 'Bun'
};
render(){
return <div> {this.state.name} </div>
}
};

If you like the restriction part where the sub-component can’t be used without importing the parent component, but dislike the name-spacing aspect. Then you can destructure the fields before usage.

import Burger from './Burger';
const { Bun } = Burger;

If you need interaction between the components and wants to let the state exists in the parent component, then here is an example of how that can be applied using the render props pattern.

Try to click the burger ingredients and see how it updates.