TAB Component with ReactJS
Tags: react
Published: 2021-07-07 22:59:40

Welcome, my name is Hugo Ferreira! Today, I'm here to teach you how to create a TAB component with ReactJS!

*Observation: I created this post considering that you know the basics of ReactJS. If you see anything wrong, please tell me!*

You can see it working at CodePen: https://codepen.io/huferr/pen/GRmZJJx

To do this, we will use a functional component called *Tab*. This component will return the HTML content. Let's define it:

```react
const Tab = () => {
  return (
    <div className="container">
      <ul className="tab-list">
        <li className="tabs active-tabs">Tab 1</li>
        <li className="tabs">Tab 2</li>
        <li className="tabs">Tab 3</li>
      </ul>
      <div className="content-container">
        <div className="content active-content"><h2>Lorem</h2></div>
        <div className="content"><h2>Ipsum</h2></div>
        <div className="content"><h2>Dolor</h2></div>
      </div>
    </div>
  );
};
```

Observe the classes called `active-tabs` and `active-content` in our **first** tab and content elements. These classes will define which component should or should not be shown, and we'll use CSS to make this happen.

What will make the tab change effect is the `active-tabs` class. When called, the style of the tab will change, making it "visible". Look the example:

![Tab component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ig0k4dzma4b75julbjnd.png)

Here's the CSS file:

```css
.container {
  width: 400px;
  height: 250px;
  background-color: #eeeded;
  border: 1px solid rgba(0, 0, 0, 0.3);
}

.tab-list {
  height: 50px;
  display: flex;
  list-style: none;
  font-size: 18px;
  padding: 0;
  margin: 0;
}

.tabs {
  width: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #80808013;
  position: relative;
  cursor: pointer;
}

.tabs:not(:last-child) {
  border-right: 1px solid rgba(0, 0, 0, 0.3);
}

.active-tabs {
  background: #eeeded;
}

.active-tabs::before {
  content: "";
  display: block;
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% + 2px);
  height: 4px;
  background: #5893f1;
}

.content {
    display: none;
    background-color: #eeeded;
    padding: 10px;
}

.active-content {
    display: flex;
}
```

As you can see, the `tabs` class has a background to represent that it has not been selected. So, when we put the `active-tabs` class, the tab style looks like it's selected.

Looking at the `content` class, we can see `display: none`, which will "hide" the content from the screen, and it will only show when we call `active-content`, which has `display: flex`. This will make the content appear.

What we have to do now is create a way to control these classes when we click on each tab, binding the element that has the `active-tabs` class with the element that has the `active-content` class.

To do that, let's import useState Hook and set our `toggleState`, which will handle the index of each tab we have.

*Obs.: Do it in the same Tab component.*

```react
import React, { useState } from "react";
```
```react
const Tab = () => {

    const [toggleState, setToggleState] = useState(1)
    
  return (
```

Now, let's define an Index for each tab we have (3).

`// Tab 1 = index 1`
`// Tab 2 = index 2, and so on...`

To make it easier to understand, let's create a function that will set the index every time we click in each tab:

```react
const toggleTab = (index) = {
        setToggleState(index)
    }
```

Then, create an `onClick` event on each tab. Call an anonymous function with our `toggleTab` function. So, for each tab, let's define an index:

```react
<ul className="tab-list">
        <li className="tabs active-tabs" onClick={() => toggleTab(1)}>Tab 1</li>
        <li className="tabs"onClick={() => toggleTab(2)}>Tab 2</li>
        <li className="tabs"onClick={() => toggleTab(3)}>Tab 3</li>
      </ul>
```

Finally, let's control the classes! For this, let's use a ternary operator inside `className=""`:

```react
 <ul className="tab-list">
        <li className={toggleState === 1 ? 'tabs active-tabs' : "tabs"} onClick={() => toggleTab(1)}>Tab 1</li>
        <li className={toggleState === 2 ? 'tabs active-tabs' : "tabs"} onClick={() => toggleTab(2)}>Tab 2</li>
        <li className={toggleState === 3 ? 'tabs active-tabs' : "tabs"} onClick={() => toggleTab(3)}>Tab 3</li>
      </ul>
```

Now, let's do it for the content:

```react
<div className="content-container">
        <div className={toggleState === 1 ? 'content active-content' : "content"}><h2>Lorem</h2></div>
        <div className={toggleState === 2 ? 'content active-content' : "content"}><h2>Ipsum</h2></div>
        <div className={toggleState === 3 ? 'content active-content' : "content"}><h2>Dolor</h2></div>
      </div>
```

Basically, we are saying that if toggleState is 1, put the class `tabs` and `active-tabs` in the Tab 1. if toggleState is 2, put the class `tabs` and `active-tabs` in the Tab 2. If not, put only `tabs` Same for the content classes.

In order to make it better, let's create a function to do this comparison:

```react
const getActiveClass = (index, className) =>
    toggleState === index ? className : "";
```
 
###Overview:###

```react
import React, { useState } from "react";
import "./styles.css";

const Tab = () => {
  const [toggleState, setToggleState] = useState(1);

  const toggleTab = (index) => {
    setToggleState(index);
  };

  const getActiveClass = (index, className) =>
    toggleState === index ? className : "";

  return (
    <div className="container">
      <ul className="tab-list">
        <li
          className={`tabs ${getActiveClass(1, "active-tabs")}`}
          onClick={() => toggleTab(1)}
        >
          Tab 1
        </li>
        <li
          className={`tabs ${getActiveClass(2, "active-tabs")}`}
          onClick={() => toggleTab(2)}
        >
          Tab 2
        </li>
        <li
          className={`tabs ${getActiveClass(3, "active-tabs")}`}
          onClick={() => toggleTab(3)}
        >
          Tab 3
        </li>
      </ul>
      <div className="content-container">
        <div className={`content ${getActiveClass(1, "active-content")}`}>
          <h2>Lorem</h2>
        </div>
        <div className={`content ${getActiveClass(2, "active-content")}`}>
          <h2>Ipsum</h2>
        </div>
        <div className={`content ${getActiveClass(3, "active-content")}`}>
          <h2>Dolor</h2>
        </div>
      </div>
    </div>
  );
};

export default Tab;

```
###Results###

![Results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wks20dwl80hq5oge9sm.png)


Done! Thanks for reading this content, I hope it helps you in some way and, if you notice something wrong, feel free to help me leaving a comment bellow or find me on [twitter](https://twitter.com/thehuferr) !

You can also find me at:

[Github](https://github.com/huferr)
[Linkedin](https://www.linkedin.com/in/hugo-ferreira-it/)