Reactで作る理解のしやすいタブのテンプレが、Qiitaに置いてあればと思い書きました。
基本的にはこちらの記事を元に作成させていただきましたが、一部修正しています。
環境
- react 18.2.0
- typescript 4.7.4
ディレクトリ構成
src/
├── components
│ ├── Tab.tsx
│ ├── TabTitle.tsx
│ └── Tabs.tsx
└── index.tsx
完成はこんな感じ
Tabs.tsx
Tabs.tsx
import { FC, ReactNode, useState } from 'react';
import TabTitle from './TabTitle';
interface Props {
children: ReactNode;
};
const Tabs: FC<Props> = ({ children }) => {
const [selectedTab, setSelectedTab] = useState(0);
return (
<div>
<ul>
{children.map((item, index) => (
<TabTitle
key={index}
title={item.props.title}
index={index}
setSelectedTab={setSelectedTab}
/>
))}
</ul>
{children[selectedTab]}
</div>
);
};
export default Tabs;
TabTitle.tsx
TabTitle.tsx
import { FC, useCallback } from 'react';
type Props = {
title: string;
index: number;
setSelectedTab: (index: number) => void;
};
const TabTitle: FC<Props> = ({ title, index, setSelectedTab }) => {
const onClick = useCallback(() => {
setSelectedTab(index);
}, [setSelectedTab, index]);
return (
<li>
<button onClick={onClick}>{title}</button>
</li>
);
};
export default TabTitle;
Tab.tsx
Tab.tsx
import { FC, ReactNode } from 'react';
type Props = {
title: string;
children: ReactNode;
};
const Tab: FC<Props> = ({ children }) => {
return <div>{children}</div>;
};
export default Tab;
index.tsx
index.tsx
import { FC } from 'react';
import Tab from '../components/Tabs/Tab';
import Tabs from '../components/Tabs/Tabs';
const index: FC = () => {
return (
<Tabs>
<Tab title='Lemon'>Lemon is yellow</Tab>
<Tab title='Strawberry'>Strawberry is red</Tab>
<Tab title='Pear'>Pear is green</Tab>
</Tabs>
);
};
export default index;