DEV Community

Cover image for Create Simple Tab Component with Pure React
Satel
Satel

Posted on

Create Simple Tab Component with Pure React

Let's create Tabbed menu and view component with pure React.

Let's define a TabItem component, pass it to the Tab and remove unnecessary nodes expect for TabItem by identifying the function's name in props.children. Use the React.useState() hook to initialize the value of the bindIndex state variable to props.defaultIndex.
And use Array.prototype.map on the collected nodes to render the tab-menu and tab-view. Define changeTab, which will be executed when clicking a <button> from the tab-menu. changeTab executes the passed callback, onTabClick and updates bindIndex, which in turn causes a re-render, evaluating the style and className of the tab-view items and tab-menu buttons according to their index.

/* App.css */
.tab-menu > button {
  cursor: pointer;
  padding: 8px 16px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
}
.tab-menu > button.focus {
  border-bottom: 2px solid #007BEF;
}
.tab-menu > button:hover {
  border-bottom: 2px solid #007BEF;
}
Enter fullscreen mode Exit fullscreen mode
// Tabs.jsx
function TabItem(props) {
  return <div {...props} />;
}

function Tabs(props) {
  const [bindIndex, setBindIndex] = React.useState(props.defaultIndex);
  const changeTab = newIndex => {
    if (typeof props.onTabClick === "function") props.onTabClick(newIndex);
    setBindIndex(newIndex);
  };
  const items = props.children.filter(item => item.type.name === "TabItem");

  return (
    <div className="wrapper">
      <div className="tab-menu">
        {items.map(({ props: { index, label } }) => (
          <button
            onClick={() => changeTab(index)}
            className={bindIndex === index ? "focus" : ""}
          >
            {label}
          </button>
        ))}
      </div>
      <div className="tab-view">
        {items.map(({ props }) => (
          <div
            {...props}
            className="tab-view_item"
            key={props.index}
            style={{ display: bindIndex === props.index ? "block" : "none" }}
          />
        ))}
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now you can use Tabs Component to render in your React application.

ReactDOM.render(
  <Tabs defaultIndex="1" onTabClick={console.log}>
    <TabItem label="A" index="1">
      Lorem ipsum
    </TabItem>
    <TabItem label="B" index="2">
      Dolor sit amet
    </TabItem>
  </Tabs>,
  document.getElementById("root")
);
Enter fullscreen mode Exit fullscreen mode

Thanks

Top comments (0)