← Back to React Course | Chapter 6: Custom Hooks & Advanced Patterns | Lesson 6 of 10

Custom Hooks को Compose करना

Hook composition building blocks stack करने जैसा है — आप कई छोटे custom hooks को एक बड़े custom hook के अंदर साथ उपयोग करते हैं कुछ ज़्यादा powerful बनाने के लिए।
Syntax
markup
function useComposed() {
  const first = useFirstHook();
  const second = useSecondHook(first);
  return { first, second };
}

Combining Multiple Hooks into One

एक custom hook सिर्फ useState जैसे built-in hooks call करने तक limited नहीं है — यह दूसरे custom hooks भी call कर सकता है। यह आपको छोटे, focused pieces से एक ज़्यादा powerful hook बनाने देता है, बिल्कुल वैसे ही जैसे components छोटे components से बनते हैं।

Note: हर individual hook को एक responsibility पर focused रखें (जैसे useToggle या useLocalStorage), फिर उन्हें जहां आपको combined behavior चाहिए वहां compose करें।
Warning: एक hook जो पांच दूसरे hooks compose करता है उतना ही hard to follow हो सकता है जितना एक giant component — अगर यह unwieldy हो जाए तो और split करें।

उदाहरण: Combining Multiple Hooks into One

markup
<!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">
function useToggle(initial) {
  const [value, setValue] = React.useState(initial);
  return [value, () => setValue(v => !v)];
}
function useCounter(start) {
  const [count, setCount] = React.useState(start);
  return [count, () => setCount(c => c + 1)];
}
function useComposed() {
  const [isOn, toggle] = useToggle(false);
  const [count, increment] = useCounter(0);
  return { isOn, toggle, count, increment };
}
function App() {
  const c = useComposed();
  return <button onClick={() => { c.toggle(); c.increment(); }}>{c.isOn ? "ON" : "OFF"} ({c.count})</button>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

A Real Example: useOnlineStatus + useLocalStorage

Composition तब shine करता है जब आप उन hooks को combine करते हैं जो हर एक अलग problem solve करते हैं। यहां, एक useLastSeen hook एक online-status hook को एक localStorage hook के साथ compose करता है, तो यह record कर सके और persist कर सके कि user आखिरी बार कब online था।

Note: Composed hook का नाम इसकी combined behavior के आधार पर रखें, उन hooks के आधार पर नहीं जो यह internally उपयोग करता है।
Warning: Composed hooks में effects को ऐसे order में run होते देखें जो आप expect नहीं करते — React effects को वैसे ही order में run करता है जैसे वे declared हैं, top to bottom।

उदाहरण: A Real Example: useOnlineStatus + useLocalStorage

markup
<!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">
function useLocalValue(key, initial) {
  const [value, setValue] = React.useState(initial);
  React.useEffect(() => { localStorage.setItem(key, value); }, [key, value]);
  return [value, setValue];
}
function useLastSeen() {
  const [lastSeen, setLastSeen] = useLocalValue("lastSeen", "never");
  return [lastSeen, () => setLastSeen(new Date().toLocaleTimeString())];
}
function App() {
  const [lastSeen, markSeen] = useLastSeen();
  return <div><p>Last seen: {lastSeen}</p><button onClick={markSeen}>Mark as seen now</button></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Keeping Composed Hooks Readable

जैसे-जैसे आप ज़्यादा hooks साथ compose करते हैं, naming और structure ज़्यादा मायने रखते हैं। हर inner hook के result को clear names के साथ destructure करना, और outer hook से एक well-named object return करना, composed hook को एक glance में समझना आसान रखता है।

Note: अगर एक composed hook के return value में 4-5 fields से ज़्यादा हैं, सोचें कि क्या यह असल में बहुत सारी unrelated चीज़ें कर रहा है।
Warning: अपने custom hooks में inconsistent shapes return करने से बचें (कभी एक array, कभी एक object) — एक convention चुनें और उस पर टिके रहें।

उदाहरण: Keeping Composed Hooks Readable

markup
<!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">
function useToggle(initial) {
  const [value, setValue] = React.useState(initial);
  return { value, toggle: () => setValue(v => !v) };
}
function useCounter(start) {
  const [count, setCount] = React.useState(start);
  return { count, increment: () => setCount(c => c + 1) };
}
function useFeature() {
  return { visibility: useToggle(true), clicks: useCounter(0) };
}
function App() {
  const { visibility, clicks } = useFeature();
  return <div>{visibility.value && <p>Clicks: {clicks.count}</p>}<button onClick={clicks.increment}>Click</button><button onClick={visibility.toggle}>Toggle</button></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. सब कुछ करने वाला एक giant hook बनाना इसके बजाय कई छोटे, focused hooks साथ compose करने के।
  2. यह न realize करना कि एक hook दूसरे custom hooks call कर सकता है — beginners कभी-कभी सोचते हैं कि सिर्फ built-in hooks combine हो सकते हैं।
  3. Hooks के बीच circular dependencies बनाना, जहां दो custom hooks हर एक दूसरे के output पर depend करने की कोशिश करते हैं।
चैप्टर सारांश
  • Hook composition का मतलब है एक custom hook को दूसरे hooks से बनाना, दूसरे custom hooks सहित।
  • यह आपको छोटे, single-purpose hooks से complex, reusable behavior (जैसे useAuthenticatedFetch) बनाने देता है।
  • हर composed hook अब भी same rules of hooks follow करता है (top-level calls, कोई conditionals नहीं)।
  • यह वैसे ही mirror करता है जैसे छोटे components बड़े components में compose होते हैं — hooks logic के लिए same way compose होते हैं।
ब्राउज़र सपोर्ट

React 16.8 (Hooks introduction) से available है — composition एक JavaScript pattern है, कोई browser feature नहीं।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.