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 ke beech mutable values kaise preserve karta hai aur direct DOM access deta hai.
useRef ek mutable object { current: value } return karta hai jo component ke poore lifetime ke liye persist karta hai. State ke unlike, ref.current mutate karne se re-render TRIGGER nahi hota. React refs ko direct DOM access ke liye ek escape hatch ke roop mein bhi use karta hai â commit phase ke baad, React ref.current ko actual DOM node set kar deta hai, aapko browser API ka imperative access deta hai.
Pehle render par, useRef(initialValue) ek object '{' current: initialValue '}' banata hai aur usse fiber ke hooks list par store karta hai. Har subsequent render par, React same object return karta hai â toh ref.current hamesha same box point karta hai.
React ref.current mutations track nahi karta. Jab aap ref.current = 5 likhte hain, React ko pata nahi chalta ki woh change hua aur koi re-render schedule nahi karega. Yeh refs ko un values ke liye ideal banata hai jo aap persist karna chahte hain lekin display nahi karna.
Jab aap ek JSX element ko ref pass karte hain (<input ref='{'myRef'}' />), React render phase ke dauran ref.current set nahi karta. Woh commit phase tak wait karta hai â DOM node exist hone ke baad â phir ref.current = domNode set karta hai.
Jab component unmount hota hai, React cleanup effects run karne se pehle ref.current = null set karta hai. Yeh aapke effects ko detached DOM node access karne se rokta hai.
Default roop se, refs function components se attach nahi ho sakti. Ek ref prop accept karne aur use DOM element ko forward karne ke liye forwardRef use karo, ya useImperativeHandle se imperative methods expose karo.
Ref object. React har render par aapko same object deta hai. current ko freely mutate karo â koi re-render nahi hoga.
Ek JSX element ko ref pass karo taaki commit ke baad ref.current mein underlying DOM node mile. Focus, scroll, aur measurement ke liye useful.
Ek function component wrap karta hai taaki woh ek ref prop accept kare aur usse inner element ko forward kare ya useImperativeHandle se expose kare.
Customize karta hai ki parent child ka ref access karne par kya dekhta hai. DOM node ki jagah, aap specific methods expose kar sakte ho.
State un values ke liye use karo jo UI affect karti hain (re-render trigger karti hain). Refs un values ke liye jo rendering affect nahi karti: 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 ka official escape hatch hai imperative code ke liye. Woh React ke declarative world ko browser APIs ke saath bridge karne dete hain jo imperative calls require karti hain (focus, scroll, animations, third-party DOM libraries). Woh effects mein stale closure problem bhi solve karte hain â ek ref ko latest state ke saath sync rakhne se aap long-running async operations ke andar safely current values access kar sakte ho.
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.