本文譯自:30-seconds-of-react 。 React 30 秒速學: 精選有用的 React 片斷,30-seconds-of-react 的中文版本,已所有完成翻譯、上線,地址:30-seconds-of-react-zh_CN-umi 。css
系列文章:react
TabItem
組件,將它傳遞給Tab
並經過在props.children
中識別函數的名稱來刪除除了TabItem
外的沒必要要的節點。React.useState()
hook 將bindIndex
狀態變量的值初始化爲props.defaultIndex
。Array.prototype.map
來渲染tab-menu
和tab-view
。changeTab
,用於 tab-menu
單擊 <button>
時執行。index
反過來從新渲染 tab-view
項的style
和className
以及tab-menu
。changeTab
執行傳遞的回調函數 onTabClick
,並更新 bindIndex
,這會致使從新渲染,根據它們的 index
改變 tab-view
項目和 tab-menu
按鈕的 style
和 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;
}
複製代碼
import styles from "./Tabs.css";
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.name);
return (
<div className={styles["wrapper"]}>
<div className={styles["tab-menu"]}>
{items.map(({ props: { index, label } }) => (
<button
onClick={() => changeTab(index)}
key={index}
className={bindIndex === index ? styles["focus"] : ""}
>
{label}
</button>
))}
</div>
<div className={styles["tab-view"]}>
{items.map(({ props }) => (
<div
{...props}
className={styles["tab-view_item"]}
key={props.index}
style={{ display: bindIndex === props.index ? "block" : "none" }}
/>
))}
</div>
</div>
);
}
複製代碼
例子git
export default function() {
return (
<Tabs defaultIndex="1" onTabClick={console.log}> <TabItem label="A" index="1"> A 選修卡的內容 </TabItem> <TabItem label="B" index="2"> B 選修卡的內容 </TabItem> </Tabs>
);
}
複製代碼