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;
}
// 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>
);
}
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")
);
Thanks
Top comments (0)