Tutorial

How to Build a Tabs Component with React

Updated on August 25, 2020
authorauthor

joshtronic and christinagorton

How to Build a Tabs Component with React

Introduction

If you’ve ever built a web app, there’s a good chance you’ve built a tabbed document interface at one point or another. Tabs allow you to break up complex interfaces into manageable subsections that a user can quickly switch between. Tabs are a common UI component and are important to understand how to implement.

In this article, you will learn how to create a reusable tab container component that you can use by itself or with your existing components.

Prerequisites

Before you begin this guide, you’ll need the following:

This tutorial was tested on Node.js version 10.20.1 and npm version 6.14.4.

Step 1 — Creating an Empty Project

In this step, you’ll create a new project using Create React App. You will then delete the sample project and related files that are installed when you bootstrap the project.

To start, make a new project. In your terminal, run the following script to install a fresh project using create-react-app:

  1. npx create-react-app react-tabs-component

After the project is finished, change into the directory:

  1. cd react-tabs-component

In a new terminal tab or window, start the project using the Create React App start script. The browser will auto-refresh on changes, so leave this script running while you work:

  1. npm start

This will start a locally running server. If the project did not open in a browser window, you can open it by visiting http://localhost:3000/. If you are running this from a remote server, the address will be http://your_domain:3000.

Your browser will load with a template React application included as part of Create React App:

React template project

You will be building a completely new set of custom components, so you’ll need to start by clearing out some boilerplate code so that you can have an empty project.

To start, open src/App.js in a text editor. This is the root component that is injected into the page. All components will start from here. You can find more information about App.js at How To Set Up a React Project with Create React App.

You will see a file like this:

react-tabs-component/src/App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

Delete the line import logo from './logo.svg';. Then replace everything in the return statement to return a set of div tags and an h1. This will give you a valid page that returns an h1 that displays Tabs Demo. The final code will look like this:

react-tabs-component/src/App.js

import React from 'react';
import './App.css';

function App() {
  return (
    <div>
      <h1>Tabs Demo</h1>
    </div>
  );
}

export default App;

Save and exit the text editor.

Finally, delete the logo. You won’t be using it in your application, and you should remove unused files as you work. It will save you from confusion in the long run.

In the terminal window type the following command to delete the logo:

  1. rm src/logo.svg

Now that the project is set up, you can create your first component.

Step 2 — Creating the Tabs Component

In this step, you will create a new folder and the Tabs component that will render each Tab.

First, create a folder in the src directory called components:

  1. mkdir src/components

Inside the components folder, create a new file called Tabs.js:

  1. nano src/components/Tabs.js

Add the following code to the new Tabs.js file:

react-tabs-component/src/components/Tabs.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Tab from './Tab';

These are the imports you need to create this component. This component will keep track of which tab is active, display a list of tabs, and the content for the active tab.

Next, add the following code that will be used to keep track of state and display the active tab below the imports in Tabs.js:

react-tabs-component/src/components/Tabs.js
...

class Tabs extends Component {
  static propTypes = {
    children: PropTypes.instanceOf(Array).isRequired,
  }

  constructor(props) {
    super(props);

    this.state = {
      activeTab: this.props.children[0].props.label,
    };
  }

  onClickTabItem = (tab) => {
    this.setState({ activeTab: tab });
  }

...

The initial state is added for the active tab and will start at 0 in the array of tabs you will be creating.

onClickTabItem will update the app state to the current tab that is clicked by the user.

Now you can add your render function to the same file:

react-tabs-component/src/components/Tabs.js
...

  render() {
    const {
      onClickTabItem,
      props: {
        children,
      },
      state: {
        activeTab,
      }
    } = this;

    return (
      <div className="tabs">
        <ol className="tab-list">
          {children.map((child) => {
            const { label } = child.props;

            return (
              <Tab
                activeTab={activeTab}
                key={label}
                label={label}
                onClick={onClickTabItem}
              />
            );
          })}
        </ol>
        <div className="tab-content">
          {children.map((child) => {
            if (child.props.label !== activeTab) return undefined;
            return child.props.children;
          })}
        </div>
      </div>
    );
  }
}

export default Tabs;

This component keeps track of which tab is active, displays a list of tabs, and the content for the active tab.

The Tabscomponent uses the next component you will create called Tab.

Step 3 — Creating the Tab Component

In this step, you will create the Tab component that you will use to create individual tabs.

Create a new file called Tab.js inside the components folder:

  1. nano src/components/Tab.js

Add the following code to the Tab.js file:

react-tabs-component/src/components/Tab.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';

Once again, you import React from react and import PropTypes. PropTypes is a special propTypes property used to run type-checking on props in a component.

Next, add the following code below the import statements:

react-tabs-component/src/components/Tab.js
...
class Tab extends Component {
  static propTypes = {
    activeTab: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    onClick: PropTypes.func.isRequired,
  };

  onClick = () => {
    const { label, onClick } = this.props;
    onClick(label);
  }

  render() {
    const {
      onClick,
      props: {
        activeTab,
        label,
      },
    } = this;

    let className = 'tab-list-item';

    if (activeTab === label) {
      className += ' tab-list-active';
    }

    return (
      <li
        className={className}
        onClick={onClick}
      >
        {label}
      </li>
    );
  }
}

export default Tab;

The PropTypes in this component are used to ensure that activeTab and label are a string and required. onClick is set to be a function that is also required.

The Tab component displays the name of the tab and adds an additional class if the tab is active. When clicked, the component will fire a handler, onClick, that will let the Tabs component know which tab should be active.

Step 4 — Adding CSS to Style the App

In addition to creating components, you will add CSS to give the components the appearance of tabs.

Inside the App.css file, remove all the default CSS and add this code:

[label react-tabs-component/src/App.css] .tab-list {
  border-bottom: 1px solid #ccc;
  padding-left: 0;
}

.tab-list-item {
  display: inline-block;
  list-style: none;
  margin-bottom: -1px;
  padding: 0.5rem 0.75rem;
}

.tab-list-active {
  background-color: white;
  border: solid #ccc;
  border-width: 1px 1px 0 1px;
}

This will make the tabs in-line and give the active tab a border to make it stand out when clicked.

Step 5 — Updating App.js

Now that the components and associated styles are in place, update the App component to use them.

First, update the imports to include the Tabs component:

react-tabs-component/src/App.js
import React from 'react';
import Tabs from "./components/Tabs";
import "./App.css";

Next, update the code in the return statement to include the imported Tabs component:

...

function App() {
  return (
    <div>
      <h1>Tabs Demo</h1>
      <Tabs>
        <div label="Gator">
          See ya later, <em>Alligator</em>!
        </div>
        <div label="Croc">
          After 'while, <em>Crocodile</em>!
        </div>
        <div label="Sarcosuchus">
          Nothing to see here, this tab is <em>extinct</em>!
        </div>
      </Tabs>
    </div>
  );
}

export default App;

The divs with associated labels give the tabs their content.

With Tabs added to the App component, you will now have a working tabbed interface that allows you to toggle between sections:

React Tabs Component

You can view this Github Repository to see the completed code.

Conclusion

In this tutorial, you built a tab component using React to manage and update your application’s state.

From here, you can learn other ways to style React components to create an even more attractive UI.

You can also follow the full How To Code in React.js series on DigitalOcean to learn even more about developing with React.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
joshtronic

author



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
4 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Is it possible to set a specific tab as active rather than default to the first one listed?

If you have any kind of esLint running it’s going to complain that this is not keyboard accessible. It will be best make them tab-able and selectable for users without a mouse if you’re going to put them out on the open web

hi joshtronic, thank you for this tutorial!

Question, what if the data that I will be displaying in tabs are from my API. How can I filter and dynamically pull the data?

I’m new to React.

Thank you joshtronic, this is a great articles and sample of code!

One question about tab.js ‘Anonymous Object’ (sorry I don’t know how to name it)

from tabs.js

render() {
    const {
      onClickTabItem,
      props: {
        children,
      },
      state: {
        activeTab,
      }
    } = this;
...

Assigning this to an javascript object without name? It is new to me and want to know more about it. Thank you very much!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.