How to Create a Custom Tab Component by Using React

Naveen DA
4 min readOct 7, 2020

--

How to create a custom tab Component using react

Quick Summary

If you haven't created your own tab component using react, then I recommend to that create one. This will teach a lot of things in react like child render, conditional render, etc.

In this article, you will learn how to create a reusable tab component in a very simple manner.

Repo Link: https://github.com/NaveenDA/react-tabs-tutorial

Demo Link: https://nkvd0.csb.app/

Simple React Tab Component Demo

Introduction

Tabs Interface provides better user experience, it split down the complex interface into a very simple manner. You can create a tab with only CSS and HTML alone but that’s not a react way.

Create an Empty Project

We are going to create use Create-React-App and make the necessary changes you want

npx create-react-app react-simple-tab

Now you get this page

Now Create a simple tab component

// filename: tab.js
import React from "react";
const Tabs = () => {
return (
<div className="tabs" >
{ /* TabPane will Place Here */ }
</div>

);
}
export default Tabs;

Here we need to validation for the Tab component that accepts only the tabPane component rather any react component, so let's create a simple tabPane component.

import React from "react";
import PropTypes from "prop-types";
const TabPane = (props) => {
return <div className="tab-pane">{props.childern}</div>;
};
TabPane.propTypes = {
name: PropTypes.string
};
export default TabPane;

The tab pane component accepts name and children.

Tab Component allows only TabPane Component

For validation a React Component that allows a specific type of component, you have two choices they are prop-types and typescript

For Javascript

Prop-types allows validating the children component and its types

Tabs.propTypes = {
children: function (props, propName, componentName) {
const prop = props[propName];
let error = null;
React.Children.forEach(prop, function (child) {
if (child.type !== TabPane) {
error = new Error(
"`" + componentName + "` children should be of type `TabPane`."
);
}
});
return error;
}
};

For Typescript

interface ITabs {
children: ReactElement<ITabPane> | Array<ReactElement<ITabPane>>;
}

In this tutorial, I am sticking with the Javascript.

Our tabs HTML structure will more or like a bootstrap’s Tab HTML structure

<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
<li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
<li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">
<h3>HOME</h3>
<p>Some content.</p>
</div>
<div id="menu1" class="tab-pane fade">
<h3>Menu 1</h3>
<p>Some content in menu 1.</p>
</div>
<div id="menu2" class="tab-pane fade">
<h3>Menu 2</h3>
<p>Some content in menu 2.</p>
</div>
</div>

This is a very basic HTML structure of the bootstrap’s tabs

Our Tab JSX structure will be

<Tabs>
<TabPane name="Tab 1" key="1">
Content of Tab Pane 1
</TabPane>
<TabPane name="Tab 2" key="2">
Content of Tab Pane 2
</TabPane>
<TabPane name="Tab 3" key="3">
Content of Tab Pane 3
</TabPane>
</Tabs>

Construct Header

For construct the header, we get all child and their props and arrange them as a ul>li structure

const { children } = this.props

React.Children.forEach(children, element => {
if (!React.isValidElement(element)) return

const { name } = element.props


})

By using this snippet, we can able to get all children name, by pushing them all in a single array we can render the full header part

Active state

For maintaining the active tab state, we need the reactive state.

const [active, setActive] = useState("");

For the first time need to active the first tab.

setActive(headers[0]);

By adding active class, we can show the active tab, but we need to show only the active content. For this we can use the class, but that not the react way.

Tab Active Section

We need to display only active content and remaining content at all we need to remove from the DOM.

<div className="tab-content">
{Object.keys(childContent).map((key) => {
if (key === active) {
return <div class="tab-child">{childContent[key]}</div>;
} else {
return null;
}
})}
</div>

We are returning the dom only for the active tab otherwise we returning the null, and this will take care by the jsx itself.

Only Active element is present in the DOM

That’s it, now you have a reusable tab Component.

If you can’t able to understand my tutorials, I have listed the best 3 tutorials that I found for your better understanding.

Best Tutorials:

  1. How to Build a Tabs Component with React
  2. Creating a tabs component with React
  3. The Anatomy of a Tablist Component in Vanilla JavaScript Versus React

--

--

Naveen DA
Naveen DA

Responses (1)