Files
siphalor.de/_posts/2018-07-12-react-component-with-dot-notation.md
2019-03-24 20:37:09 +07:00

3.3 KiB
Raw Blame History

title, date, modified, categories, tags, image
title date modified categories tags image
React Component with Dot Notation 2019-02-19 11:45:47 +07:00 2019-02-20 11:45:47 +07:00 tips
react
javascript
dot-notation

This is my answer to someones 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, its actually a pretty common pattern. And its not really a sub-component, its just another component being attached to another one.

Lets use the above Menucomponent for example. Well put this component to its own dedicated file: menu.js. First, lets 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>;

Its 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'));

Wheres 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>
    );
  }
}

For demo purpose, Originally published at https://bagja.net.