标签页
渲染一个带有标签菜单和视图的组件。
- 定义一个
Tabs
组件。使用useState()
钩子将bindIndex
状态变量的初始值设为defaultIndex
。 - 定义一个
TabItem
组件,并通过识别函数的名称,过滤传递给Tabs
组件的children
,以删除不必要的节点,只保留TabItem
。 - 定义
changeTab
函数,当点击菜单中的<button>
时执行。 changeTab
函数执行传递的回调函数onTabClick
,并根据点击的元素更新bindIndex
。- 使用
Array.prototype.map()
在收集到的节点上渲染标签菜单和视图。 - 使用
bindIndex
的值来确定活动标签,并应用正确的className
。
.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;
}
.tab-content {
display: none;
}
.tab-content.selected {
display: block;
}
const TabItem = props => <div {...props} />;
const Tabs = ({ defaultIndex = 0, onTabClick, children }) => {
const [bindIndex, setBindIndex] = React.useState(defaultIndex);
const changeTab = newIndex => {
if (typeof onTabClick === 'function') onTabClick(newIndex);
setBindIndex(newIndex);
};
const items = children.filter(item => item.type.name === 'TabItem');
返回 (
<div className="wrapper">
<div className="tab-menu">
{items.map(({ props: { index, label } }) => (
<button
key={`tab-btn-${index}`}
onClick={() => changeTab(index)}
className={bindIndex === index ? 'focus' : ''}
>
{label}
</button>
))}
</div>
<div className="tab-view">
{items.map(({ props }) => (
<div
{...props}
className={`tab-content ${
bindIndex === props.index ? 'selected' : ''
}`}
key={`tab-content-${props.index}`}
/>
))}
</div>
</div>
);
ReactDOM.createRoot(document.getElementById('root')).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>
);