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

useToggle Hook बनाना

एक useToggle hook एक light switch जैसा है जो आप एक बार बना सकते हैं और हर जगह reuse कर सकते हैं जहां आपको एक on/off button चाहिए।
Syntax
markup
function useToggle(initial = false) {
  const [value, setValue] = useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle];
}

const [isOn, toggle] = useToggle(false);

Building a Minimal useToggle

एक toggle सबसे simple और common pieces of UI state में से एक है: एक sidebar या तो open है या closed, एक checkbox या तो checked है या नहीं। useToggle इस pattern को एक two-item return में wrap करता है: current boolean value और इसे flip करने के लिए एक function।

Note: Hook को एक default value parameter दें (जैसे useToggle(false)) ताकि callers starting state choose कर सकें।
Warning: इसे उपयोग करते समय hook के return value को कुछ generic जैसे value नाम न दें — call site पर इसे isOpen जैसा एक meaningful नाम देकर destructure करें।

उदाहरण: Building a Minimal useToggle

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 = false) {
  const [value, setValue] = React.useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle];
}
function App() {
  const [isOpen, toggleOpen] = useToggle(false);
  return (
    <div>
      <button onClick={toggleOpen}>Toggle Menu</button>
      {isOpen && <p>Menu is open!</p>}
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Why the Functional Updater Matters

setValue(!value) लिखना उस render से value पढ़ता है जहां function बना था, जो stale हो सकता है अगर कई toggles quickly होते हैं (जैसे एक fast double-click)।

सेटValue(v => !v) लिखना इसके बजाय हमेशा जो भी actual latest state है उसे flip करता है, उस bug से बचते हुए।

Note: एक habit के रूप में, custom hooks के अंदर हमेशा functional updater form उपयोग करें, क्योंकि आप control नहीं करते कि caller उन्हें कितनी बार या कितनी तेज़ invoke करे।
Warning: एक ही event handler में setValue(!value) को दो rapid calls दोनों same stale value से compute कर सकते हैं और एक-दूसरे को cancel करने के बजाय दो बार toggle करने की उम्मीद थी।

उदाहरण: Why the Functional Updater Matters

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 = false) {
  const [value, setValue] = React.useState(initial);
  const toggle = () => setValue(v => !v);
  return [value, toggle];
}
function App() {
  const [isOn, toggle] = useToggle(false);
  const toggleTwice = () => { toggle(); toggle(); };
  return <div><p>State: {isOn ? "ON" : "OFF"}</p><button onClick={toggleTwice}>Toggle Twice (stays same)</button></div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Extending useToggle with Explicit Setters

कभी-कभी एक caller को value को directly true या false force करना होता है, सिर्फ इसे flip नहीं करना — उदाहरण के लिए, बाहर click करने पर एक modal को explicitly बंद करना। toggle, setTrue, और setFalse वाला एक object return करना callers को वह extra control देता है।

Note: यहां एक object return करना (array के बजाय) एक अच्छा choice है क्योंकि distinct purposes वाले तीन related functions हैं।
Warning: अगर आप setTrue/setFalse जोड़ें, सुनिश्चित करें कि वे भी directly setValue(true)/setValue(false) उपयोग करें toggle() पर दो बार depend करने के बजाय, behavior को predictable रखने के लिए।

उदाहरण: Extending useToggle with Explicit Setters

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 = false) {
  const [value, setValue] = React.useState(initial);
  return { value, toggle: () => setValue(v => !v), setTrue: () => setValue(true), setFalse: () => setValue(false) };
}
function App() {
  const modal = useToggle(false);
  return (
    <div>
      <button onClick={modal.setTrue}>Open Modal</button>
      {modal.value && <div><p>Modal content</p><button onClick={modal.setFalse}>Close</button></div>}
    </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. हर component में same 'const [on, setOn] = useState(false); const toggle = () => setOn(!on);' logic फिर से बनाना इसे extract करने के बजाय।
  2. setOn(!on) उपयोग करना functional form setOn(o => !o) के बजाय, जो rapid clicks में stale state पढ़ सकता है।
  3. Caller को सिर्फ toggle करने से ज़्यादा control चाहिए होने पर explicit setTrue/setFalse setters भी expose करना भूल जाना।
चैप्टर सारांश
  • useToggle एक छोटा custom hook है जो एक toggle function के साथ एक single boolean value manage करता है।
  • यह useState के ऊपर बना एक simplification है, menus, modals, और switches के लिए useful।
  • Functional state updater form उपयोग करना stale closures से bugs को रोकता है।
  • यह अक्सर explicit setTrue/setFalse functions को toggle के साथ भी return करने के लिए extended होता है।
ब्राउज़र सपोर्ट

React 16.8 (Hooks introduction) से available है — कोई special browser requirements नहीं।

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.