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:
You will need a development environment running Node.js. To install this on macOS or Ubuntu 18.04, follow the steps in How to Install Node.js and Create a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.
In this tutorial, you will create apps with Create React App. You can find instructions for installing an application with Create React App at How To Set Up a React Project with Create React App
You will also need a basic knowledge of JavaScript, which you can find in How To Code in JavaScript, along with a basic knowledge of HTML and CSS. A good resource for HTML and CSS is the Mozilla Developer Network.
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
:
npx create-react-app react-tabs-component
After the project is finished, change into the directory:
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:
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:
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:
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
:
mkdir src/components
Inside the components
folder, create a new file called Tabs.js
:
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 `` 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 Tabs
component 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:
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 div
s 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:
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.