Compound Component Pattern क्या है
In this page:
const ParentContext = createContext();
function Parent({ children }) {
const [state, setState] = useState(initial);
return (
<ParentContext.Provider value={{ state, setState }}>
{children}
</ParentContext.Provider>
);
}
Parent.Child = function Child() {
const { state } = useContext(ParentContext);
return <div>{state}</div>;
};
Components को 'Compound' क्या बनाता है
Compound components कई components हैं जिन्हें एक set के रूप में साथ उपयोग करने का मतलब है, जैसे HTML का <select> और <option>। एक huge configuration prop accept करने वाले एक component के बजाय, API को छोटे pieces में तोड़ा जाता है जो shared context के through implicitly communicate करते हैं, caller को ज़्यादा layout freedom देते हुए।
उदाहरण: What Makes Components 'Compound'
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const TabsContext = React.createContext();
function Tabs({ children, defaultTab }) {
const [active, setActive] = React.useState(defaultTab);
return <TabsContext.Provider value={{ active, setActive }}>{children}</TabsContext.Provider>;
}
function Tab({ id, children }) {
const { active, setActive } = React.useContext(TabsContext);
return <button onClick={() => setActive(id)} style={{fontWeight: active === id ? "bold" : "normal"}}>{children}</button>;
}
function App() {
return <Tabs defaultTab="a"><Tab id="a">Tab A</Tab><Tab id="b">Tab B</Tab></Tabs>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Props के बजाय Context के through State Share करना
हर level पर explicit props के through active tab पास करने के बजाय, compound components shared state को parent द्वारा provided एक Context में store करते हैं।
कोई भी sub-component फिर सीधे उस context को पढ़ सकता है, चाहे यह parent के children के अंदर कितना भी deep nested हो।
उदाहरण: Sharing State via Context Instead of Props
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const PanelContext = React.createContext();
function Accordion({ children }) {
const [openIndex, setOpenIndex] = React.useState(null);
return <PanelContext.Provider value={{ openIndex, setOpenIndex }}>{children}</PanelContext.Provider>;
}
function Panel({ index, title, children }) {
const { openIndex, setOpenIndex } = React.useContext(PanelContext);
const isOpen = openIndex === index;
return <div><button onClick={() => setOpenIndex(isOpen ? null : index)}>{title}</button>{isOpen && <p>{children}</p>}</div>;
}
function App() {
return <Accordion><Panel index={0} title="Section 1">Content 1</Panel><Panel index={1} title="Section 2">Content 2</Panel></Accordion>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
एक Clean API के लिए Sub-Components Attach करना
एक common finishing touch sub-components को main component की properties के रूप में attach करना है, जैसे Tabs.Tab = Tab। यह consumers को सिर्फ एक नाम (Tabs) import करने देता है और इसके through सब कुछ access करने देता है, related pieces को obviously connected बनाते हुए।
उदाहरण: Attaching Sub-Components for a Clean API
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const TabsContext = React.createContext();
function Tabs({ children, defaultTab }) {
const [active, setActive] = React.useState(defaultTab);
return <TabsContext.Provider value={{ active, setActive }}>{children}</TabsContext.Provider>;
}
function Tab({ id, children }) {
const { active, setActive } = React.useContext(TabsContext);
return <button onClick={() => setActive(id)} style={{fontWeight: active === id ? "bold" : "normal"}}>{children}</button>;
}
Tabs.Tab = Tab;
function App() {
return <Tabs defaultTab="x"><Tabs.Tab id="x">X</Tabs.Tab><Tabs.Tab id="y">Y</Tabs.Tab></Tabs>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
- Context के through shared state setup किए बिना compound components उपयोग करना, pieces के बीच awkward prop-drilling मजबूर करते हुए।
- Sub-components को parent की properties के रूप में export न करना (जैसे Tabs.Panel), API को कम discoverable बनाते हुए।
- Sub-components को इनके parent के बाहर उपयोग होने देना, जहां इनके पास कोई shared context नहीं है और चुपचाप fail होते हैं।
- Compound components components का एक set हैं जो साथ काम करने के लिए designed हैं, Context के through implicit state share करते हुए।
- Classic example एक Tabs component है जो Tabs, Tabs.List, Tabs.Tab, और Tabs.Panel से मिलकर साथ काम करता है।
- यह pattern consumer को layout पर flexible control देता है जबकि parent internally shared state manage करता है।
- यह आमतौर पर React Context उपयोग करके implement होता है state को manual prop drilling के बिना नीचे pass करने के लिए।
React 16.3 (stable Context API) से available है — पहले की versions इसे React.Children/cloneElement से approximate कर सकती थीं।
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: