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

useLayoutEffect Hook का उपयोग

useLayoutEffect useEffect के ज़्यादा urgent sibling जैसा है जो नई picture दिखने से पहले ही अपना काम खत्म करने पर insist करता है।
Syntax
markup
useLayoutEffect(() => {
  // runs after DOM updates, before the browser paints
  return () => {
    // optional cleanup
  };
}, [dependency]);

How useLayoutEffect Differs from useEffect

दोनों Hooks आपको render होने के बाद code run करने देते हैं, लेकिन useEffect browser के पहले से paint होने के बाद asynchronously run होता है, जबकि useLayoutEffect paint होने से पहले synchronously run होता है।

इसका मतलब है कि useLayoutEffect एक visible flicker को रोक सकता है जब इसे measurements के आधार पर layout adjust करने की ज़रूरत हो।

Note: almost हर चीज़ के लिए useEffect को default मानें -- useLayoutEffect पर switch सिर्फ तब करें जब आपको specifically एक visual flicker दिखे जिसे fix करना है।
Warning: क्योंकि useLayoutEffect finish होने तक painting को block करता है, इसके अंदर का slow code page के जल्दी responsive दिखने में noticeably delay कर सकता है।

उदाहरण: How useLayoutEffect Differs from useEffect

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 LayoutDemo() {
      const boxRef = React.useRef(null);
      React.useLayoutEffect(() => {
        if (boxRef.current) {
          console.log("Box width before paint:", boxRef.current.offsetWidth);
        }
      }, []);
      return <div ref={boxRef} style={{width: "200px", padding: "10px", background: "lightblue"}}>Measured box</div>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<LayoutDemo />);
  </script>
</body>
</html>

A Typical Use Case: Avoiding Flicker

useLayoutEffect के लिए एक common case एक element को measure करना है (जैसे इसकी height) और फिर immediately उस measurement के आधार पर कुछ और adjust करना, जैसे एक tooltip positioning करना।

इसे useEffect के साथ करने से सही होने से पहले गलत position का एक brief, visible flash हो सकता है।

Note: अगर आपका effect DOM measure करता है और फिर immediately उस measurement के आधार पर styles update करता है, तो यह classic useLayoutEffect scenario है।
Warning: ज़्यादातर components को इसकी कभी ज़रूरत नहीं पड़ती -- इसे सिर्फ तब उपयोग करें जब आपने एक layout-dependent effect की वजह से एक actual visual flicker identify किया हो।

उदाहरण: A Typical Use Case: Avoiding Flicker

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 Tooltip({ text }) {
      const ref = React.useRef(null);
      const [width, setWidth] = React.useState(0);
      React.useLayoutEffect(() => {
        setWidth(ref.current.offsetWidth);
      }, [text]);
      return <span ref={ref}>{text} (width: {width}px)</span>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Tooltip text="Hover tip" />);
  </script>
</body>
</html>

Server-Side Rendering Considerations

एक server पर (किसी browser involved होने से पहले), measure करने के लिए कोई असली layout नहीं है, इसलिए useLayoutEffect वहां एक console warning produce करता है और असल में run नहीं होता। एक purely browser-based setup में (इस course के examples जैसा), यह कोई concern नहीं है।

Note: अगर आप server-side rendering वाला एक app बना रहे हैं (जैसे Next.js), इस specific warning पर ध्यान दें और सोचें कि क्या useEffect भी बराबर अच्छी तरह काम करेगा।
Warning: एक server-rendered app में 'useLayoutEffect does nothing on the server' देखना expected है -- यह आपके code के broken होने का sign नहीं है।

उदाहरण: Server-Side Rendering Considerations

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 ClientOnlyMeasurement() {
      const ref = React.useRef(null);
      const [height, setHeight] = React.useState(null);
      React.useLayoutEffect(() => {
        setHeight(ref.current.offsetHeight);
      }, []);
      return <div ref={ref}><p>Measured height: {height ?? "measuring..."}</p></div>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<ClientOnlyMeasurement />);
  </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. useEffect के बजाय default रूप से useLayoutEffect पर पहुंचना, even जबकि useEffect almost सभी cases के लिए सही है।
  2. यह न realize करना कि useLayoutEffect synchronously run होता है और browser को paint करने से block कर सकता है, overuse होने पर perceived performance hurt करते हुए।
  3. Server पर (server-side rendering में) useLayoutEffect उपयोग करना जहां यह एक warning produce करता है, क्योंकि अभी measure करने के लिए कोई browser layout नहीं है।
चैप्टर सारांश
  • useLayoutEffect की API useEffect जैसी ही है लेकिन यह अलग समय पर fire होता है।
  • यह DOM mutations के बाद लेकिन browser के screen paint करने से पहले synchronously run होता है।
  • यह मुख्यतः layout measure करने और user को कुछ भी दिखने से पहले DOM adjustments करने के लिए उपयोग होता है।
  • useEffect default रूप से preferred है; useLayoutEffect layout-measurement edge cases के लिए reserved है।
ब्राउज़र सपोर्ट

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.