Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
useRef कैसे renders के बीच mutable values को बनाए रखता है और DOM access देता है।
useRef एक mutable object { current: value } return करता है जो component के पूरे lifetime तक persist करता है। State के विपरीत, ref.current को mutate करने से re-render trigger नहीं होता। React refs को direct DOM access के लिए escape hatch के रूप में भी उपयोग करता है — commit phase के बाद, React ref.current को actual DOM node पर set करता है, जिससे आपको browser API का imperative access मिलता है।
पहले render पर, useRef(initialValue) object '{' current: initialValue '}' बनाता है और fiber के hooks list पर store करता है। प्रत्येक subsequent render पर, React same object return करता है — इसलिए ref.current हमेशा same box को point करता है।
React ref.current mutations track नहीं करता। जब आप ref.current = 5 लिखते हैं, React को पता नहीं चलता कि यह बदला और re-render schedule नहीं करेगा। यह refs को उन values के लिए ideal बनाता है जो persist करनी हैं लेकिन display नहीं करनी।
जब आप JSX element को ref pass करते हैं (<input ref='{'myRef'}' />), React render phase के दौरान ref.current set नहीं करता। यह commit phase तक इंतज़ार करता है — DOM node exist होने के बाद — फिर ref.current = domNode set करता है।
जब component unmount होता है, React cleanup effects चलाने से पहले ref.current = null set करता है। यह आपके effects को detached DOM node access करने से रोकता है।
Default में, refs को function components से attach नहीं किया जा सकता। forwardRef का उपयोग करें ref prop accept करने और DOM element को forward करने के लिए, या useImperativeHandle के ज़रिए imperative methods expose करने के लिए।
Ref object। React हर render पर same object देता है। current को freely mutate करें — कोई re-render नहीं होगा।
JSX element को ref pass करने से commit के बाद ref.current में underlying DOM node मिलता है। Focus, scroll, और measurement के लिए useful।
एक function component को wrap करता है ताकि ref prop accept करे और inner element को forward करे या useImperativeHandle के ज़रिए expose करे।
Parent के लिए customize करता है कि वह child के ref access करने पर क्या देखे। DOM node की बजाय आप specific methods expose कर सकते हैं।
UI को affect करने वाली values के लिए state उपयोग करें (re-render trigger करता है)। Rendering को affect न करने वाली values के लिए refs: timers, DOM nodes, previous values, flags।
1// 1. DOM access — focus an input programmatically2const inputRef = useRef(null);3<input ref={inputRef} />4// After mount: inputRef.current is the <input> DOM node5inputRef.current.focus(); // imperative DOM call67// 2. Persist a value without re-rendering8const timerRef = useRef(null);9timerRef.current = setInterval(tick, 1000);10// Later:11clearInterval(timerRef.current);1213// 3. Read latest state in a stale closure14const countRef = useRef(count);15countRef.current = count; // sync on every render16useEffect(() => {17 const interval = setInterval(() => {18 console.log(countRef.current); // always latest value19 }, 1000);20 return () => clearInterval(interval);21}, []); // empty deps — no stale closure problem
Refs React का official escape hatch है imperative code के लिए। ये React की declarative दुनिया को browser APIs के साथ bridge करते हैं जिन्हें imperative calls चाहिए (focus, scroll, animations, third-party DOM libraries)। ये effects में stale closure problem भी solve करते हैं — latest state के साथ ref sync रखकर, आप long-running async operations के अंदर safely current values access कर सकते हैं।
A multi-step checkout form should automatically focus the first empty field when the user navigates to a new step. Using state to track focus causes infinite re-renders.
Attempting to manage focus with useState creates a loop: setState triggers re-render, re-render re-focuses, which fires onFocus, which might set state again. Focus is an imperative DOM operation — it doesn't fit React's declarative model.
Use a ref to directly call `.focus()` on the input DOM node: `useEffect(() => { inputRef.current?.focus() }, [currentStep])`. The ref gives you direct DOM access without triggering re-renders. Focus management is inherently imperative — refs are React's bridge to imperative DOM APIs.
Takeaway: Use refs for imperative DOM operations that don't produce visual output (focus, scroll, measure, select text, play/pause media). These operations are side effects that bypass React's virtual DOM — refs give you a controlled escape hatch.
You need to compare the current value with the previous value to show a 'price changed' animation. Storing the previous value in state causes an extra re-render on every change.
Using `useState(previousPrice)` to track the old price means: price changes → re-render with new price → useEffect sets previousPrice → ANOTHER re-render. Two renders for one price change, and the animation triggers late.
Use a ref: `const prevPriceRef = useRef(price)`. In useEffect, compare `price !== prevPriceRef.current`, trigger the animation, then update: `prevPriceRef.current = price`. Refs update without re-rendering — you get the comparison for free, no extra render cycle.
Takeaway: Refs are the correct tool for 'instance variables' — values that need to persist across renders but shouldn't trigger re-renders when updated. Common patterns: previous values, timer IDs, DOM nodes, external library instances, and accumulator values.