はじめに
表題通り、ReactでProviderを利用します。
成果物
設計
・親コンポーネント以下では、Tabの情報が更新可能にする
・子コンポーネントのHeaderでは、Tab情報の更新
・子コンポーネントのContentでは、Tab情報を取得し表示を切り替える
ソースコード
App.tsx
import { Content } from "./Content";
import { Header } from "./Header";
import { TabProvider } from "./TabContext";
const App: React.FC = () => {
return (
<TabProvider>
<Header />
<Content />
</TabProvider>
);
};
export default App;
TabContext.tsx
import React, { useState, createContext, useContext, ReactNode } from "react";
export interface TabContextType {
activeTab: number;
setActiveTab: (index: number) => void;
}
export const TabContext = createContext<TabContextType | undefined>(undefined);
export interface TabProviderProps {
children: ReactNode;
}
export const TabProvider: React.FC<TabProviderProps> = ({ children }) => {
const [activeTab, setActiveTab] = useState(0);
return (
<TabContext.Provider value={{ activeTab, setActiveTab }}>
{children}
</TabContext.Provider>
);
};
Header.tsx
import { useContext } from "react";
import { TabContext } from "./TabContext";
const TABS = ["Tab1", "Tab2", "Tab3", "Tab4"];
export const Header: React.FC = () => {
const context = useContext(TabContext);
if (!context) {
throw new Error("Header must be used within a TabProvider");
}
const { activeTab, setActiveTab } = context;
return (
<div>
{TABS.map((tab, index) => (
<button key={index} onClick={() => setActiveTab(index)}>
{tab}
</button>
))}
</div>
);
};
Content.tsx
import { useContext } from "react";
import { TabContext } from "./TabContext";
export const Content: React.FC = () => {
const context = useContext(TabContext);
if (!context) {
throw new Error("Content must be used within a TabProvider");
}
const { activeTab } = context;
return (
<div>
{activeTab === 0 && <div>Content for Tab 1</div>}
{activeTab === 1 && <div>Content for Tab 2</div>}
{activeTab === 2 && <div>Content for Tab 3</div>}
{activeTab === 3 && <div>Content for Tab 4</div>}
</div>
);
};