🎶 Sym - 一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)平台

📕 思源笔记 - 一款桌面端笔记应用,支持 Windows、Mac 和 Linux

🎸 Solo - B3log 分布式社区的博客端节点,欢迎加入下一代社区网络

♏ Vditor - 一款浏览器端的 Markdown 编辑器

React Visual - Tab 组件

2019-10-14

描述

渲染一个 Tab 菜单及其视图组件。

  • 定义一个 TabItem 组件,可以传递给 Tab 且只接受 props.children 中通过函数名称认证的 TabItem,其余节点需要进行移除
  • 使用 React.useState() hook 初始化 bindIndex 状态变量的值为 props.defaultIndex
  • 使用 Array.prototype.map 将收集的节点渲染为 tab-menutab-view
  • 当点击 tab-menu 中的 <button> 时,将会执行定义为 changeTab 的函数
  • changeTab 执行传递的回调 onTabClick 并更新 bindIndex,这会导致重新渲染,通过他们的 index 重新计算 tab-view 中每一项的 styleclassName,以及 tab-menu 按钮

实现

.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')
);

返回总目录

每天 30 秒系列之 React


欢迎注册黑客派社区,开启你的博客之旅。让学习和分享成为一种习惯!

留下你的脚步