React Component with Dot Notation

This article is for Demo purpose

The article was originally on this repo

This is my answer to someone’s question on StackOverflow. How can we define a React component that is accessible through the dot notation?

Take a look at the following code. We have the Menu component and its three children Menu.Item:

const App = () => (
  <Menu>
    <Menu.Item>Home</Menu.Item>
    <Menu.Item>Blog</Menu.Item>
    <Menu.Item>About</Menu.Item>
  </Menu>
);

How can we define a component like Menu? Where it has some kind of “sub-component” that is accessible through a dot notation.

Well, it’s actually a pretty common pattern. And it’s not really a sub-component, it’s just another component being attached to another one.

Let’s use the above Menu component for example. We’ll put this component to its own dedicated file: menu.js. First, let’s define these two components separately on this module file:

// menu.js
import React from 'react';

export const MenuItem = ({ children }) => <li>{children}</li>;

export default const Menu = ({ children }) => <ul>{children}</ul>;

It’s just a simple functional component. The Menu is the parent with ul tag. And the MenuItem will act as its children. Now we can use these two components like so:

import React from "react";
import { render } from "react-dom";
import Menu, { MenuItem } from "./menu";

const App = () => (
  <Menu>
    <MenuItem>Home</MenuItem>
    <MenuItem>Blog</MenuItem>
    <MenuItem>About</MenuItem>
  </Menu>
);

render(<App />, document.getElementById("root"));

Where’s the dot notation? To make our MenuItem component accessible through the dot nation, we can simply attach it to the Menu component as a static property. To do so, we can no longer use the functional component for Menu and switch to the class component instead:

// menu.js
import React, { Component } from 'react';

export default const MenuItem = ({ children }) => <li>{children}</li>;

export default class Menu extends Component {
  static Item = MenuItem;

  render() {
    return (
      <ul>{this.props.children}</ul>
    );
  }
}

Now we can use the dot notation to declare the MenuItem component:

import React from "react";
import { render } from "react-dom";
import Menu from "./menu";

const App = () => (
  <Menu>
    <Menu.Item>Home</Menu.Item>
    <Menu.Item>Blog</Menu.Item>
    <Menu.Item>About</Menu.Item>
  </Menu>
);

render(<App />, document.getElementById("root"));

You can also put the MenuItem component definition directly within the Menu class. But this way you can no longer import MenuItem individually.

import React, { Component } from "react";

export default class Menu extends Component {
  static Item = ({ children }) => <li>{children}</li>;

  render() {
    return <ul>{this.props.children}</ul>;
  }
}

This article is for Demo purpose

The article was originally on this repo