問題一覧に戻る
上級高度なパターンと型
問題91: 複合コンポーネント

共有状態を持つ関連コンポーネントを組織化する複合コンポーネントパターンを学びます。コンポーネントはcontextを通じて協力し、柔軟なAPIを作成します。このパターンはネイティブHTMLのselect/optionのような直感的なコンポーネント合成を可能にします。タブ、アコーディオン、ドロップダウンなどのUIライブラリで一般的で、関心事の明確な分離を実現します。

import React, { createContext, useContext, useState } from 'react';

{/* 複合用の共有context */}
const TabsContext = ();

{/* メインコンテナコンポーネント */}
function Tabs({ children, defaultTab = 0 }) {
const [activeTab, setActiveTab] = useState(defaultTab);

return (
<TabsContext.Provider value={{ , }}>
<div>{children}</div>
</TabsContext.Provider>
);
}

{/* contextを使用するサブコンポーネント */}
function Tab({ index, children }) {
const { activeTab } = (TabsContext);
return activeTab === index ? <div>{children}</div> : null;
}

{/* 制御コンポーネント */}
function TabList({ children }) {
const { setActiveTab } = useContext();

return (
<div>
{React.Children.map(children, (child, i) =>
React.cloneElement(child, { onClick: () => (i) })
)}
</div>
);
}

{/* 複合の使用例 */}
function App() {
return (
<Tabs>
<TabList>
<button>Tab 1</button>
<button>Tab 2</button>
</TabList>
<Tab index={0}>Content 1</Tab>
<Tab index={}>Content 2</Tab>
</Tabs>
);
}

export default App;