← Back to React Course | Chapter 5: Core Hooks | Lesson 8 of 12

useCallback Hook का उपयोग

useCallback React का एक specific instruction sheet की एक copy save करना है, ताकि यह हर बार नई copy लिखने के बजाय exact वही एक फिर से दे सके।
Syntax
markup
const memoizedFunction = useCallback(() => {
  // function body
}, [dependency]);

Why Function References Matter

हर बार जब एक component render होता है, इसके अंदर defined कोई भी function एक brand-new function के रूप में फिर से बनता है, even अगर इसका code identical दिखे। यह मायने रखता है जब वह function एक prop के रूप में React.memo में wrapped एक child को pass किया जाता है, क्योंकि एक नई function reference child को यह सोचने पर मजबूर करती है कि इसके props change हो गए।

Note: Function identity ('क्या यह पहले जैसा ही function है') वह है जो React.memo check करता है -- सिर्फ यह नहीं कि अंदर का code जैसा दिखता है।
Warning: एक inline arrow function directly एक prop के रूप में pass करना इसे हर render फिर से बनाता है, जो एक child की React.memo optimization को defeat कर सकता है।

उदाहरण: Why Function References Matter

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 Parent() {
      const [count, setCount] = React.useState(0);
      function handleClick() { console.log("Clicked"); } // recreated every render
      return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Parent />);
  </script>
</body>
</html>

Memoizing a Function with useCallback

useCallback(fn, dependencies) renders के बीच वही function reference return करता है, जब तक listed dependencies change न हुई हों। यह आपको memoized child components को एक genuinely stable function reference pass करने देता है।

Note: useCallback को receiving child component पर React.memo के साथ pair करें -- किसी एक को बिना दूसरे के उपयोग करना कोई असली benefit नहीं देता।
Warning: अगर आप callback के dependency array में उपयोग किया गया एक variable list करना भूल जाएं, तो callback उस variable की एक stale, outdated value उपयोग करेगा।

उदाहरण: Memoizing a Function with useCallback

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 Button({ onClick, label }) {
      return <button onClick={onClick}>{label}</button>;
    }
    const MemoButton = React.memo(Button);
    function Parent() {
      const [count, setCount] = React.useState(0);
      const handleClick = React.useCallback(() => {
        console.log("Stable callback");
      }, []);
      return <div><p>{count}</p><MemoButton onClick={handleClick} label="Click" /><button onClick={() => setCount(count + 1)}>+1</button></div>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Parent />);
  </script>
</body>
</html>

useCallback vs useMemo

useCallback और useMemo उसी underlying problem को थोड़े अलग तरीकों से solve करते हैं: useMemo एक calculated VALUE cache करता है, जबकि useCallback खुद एक FUNCTION cache करता है। असल में, useCallback(fn, deps) वैसे ही behave करता है जैसे useMemo(() => fn, deps)।

Note:
  • जब आपको एक computed result cache करना हो तो useMemo उपयोग करें
  • जब आपको specifically एक function reference cache करना हो तो useCallback उपयोग करें।
Warning: दोनों syntaxes को confuse करना -- जैसे एक function को useMemo में wrap करना बिना इसे किसी inner function से return किए -- एक common typo-level mistake है।

उदाहरण: useCallback vs useMemo

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 Demo() {
      const [n, setN] = React.useState(1);
      const doubled = React.useMemo(() => n * 2, [n]); // caches a VALUE
      const logDoubled = React.useCallback(() => console.log(doubled), [doubled]); // caches a FUNCTION
      return <button onClick={logDoubled}>Doubled: {doubled}</button>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Demo />);
  </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. हर function को default रूप से useCallback में wrap करना, even ऐसे functions को भी जिनकी इसके लिए कोई real performance need नहीं।
  2. Callback जिन values को close over करता है उन्हें इसके dependency array में शामिल करना भूल जाना, इसे stale data उपयोग करवाते हुए।
  3. यह उम्मीद करना कि useCallback अकेला एक child component को re-render होने से रोकेगा -- इसका यह effect होने के लिए इसे child पर React.memo के साथ pair होना चाहिए।
चैप्टर सारांश
  • useCallback एक function को memoize करता है ताकि वही function reference renders के बीच reuse हो।
  • यह तब useful है जब React.memo में wrapped child components को callbacks pass करें।
  • एक stable reference के बिना, हर render एक नया function बनता है, children में memoization defeat करते हुए।
  • useMemo की तरह, इसे genuine performance needs के लिए उपयोग किया जाना चाहिए, default रूप से हर जगह नहीं।
ब्राउज़र सपोर्ट

React 16.8 से available है, जब Hooks introduce हुए थे।

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.