Renders a tabbed menu and view component.
- Define a
TabItemcomponent, pass it to theTaband remove unnecessary nodes expect forTabItemby identifying the function’s name inprops.children. - Use the
React.useState()hook to initialize the value of thebindIndexstate variable toprops.defaultIndex. - Use
Array.prototype.mapon the collected nodes to render thetab-menuandtab-view. - Define
changeTab, which will be executed when clicking a<button>from thetab-menu. changeTabexecutes the passed callback,onTabClickand updatesbindIndex, which in turn causes a re-render, evaluating thestyleandclassNameof thetab-viewitems andtab-menubuttons according to theirindex.
代码实现
.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;
}
使用样例
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>
);
}
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')
);