
React me Refs aur useRef Hook kaise use karein? Is practical guide me DOM manipulation aur performance optimization ko clean code se seekhein.
क्या आपके साथ कभी ऐसा हुआ है कि आप ReactJS में काम कर रहे हों और अचानक आपको किसी input element पर focus ले जाना हो, किसी animations को handle करना हो, या फिर किसी video elements को programmatically control करना हो? दोस्तों, जब भी हम React में काम करते हैं, तो हमारा सामना declarative state Management से होता है। लेकिन कई बार ऐसा समय आता है जब हमें React के Virtual DOM से बाहर निकलकर direct HTML DOM nodes के साथ छेड़छाड़ करनी पड़ती है। यहीं पर entry होती है Refs और useRef Hook की!
⚡ Quick Answer: React me Refs aur useRef Hook ka use direct DOM elements ko reference karne aur aisi mutable values ko store karne ke liye kiya jata hai jo update hone par component ko re-render nahi karti hain. Yeh declarative data flow se bahar nikal kar HTML DOM nodes ko manipulate karne ka sabse clean aur safe tarika hai.
React me Refs kya hote hain aur inki zaroorat kyun padti hai?
मेरे प्यारे दोस्तों, सबसे पहले यह समझते हैं कि आखिर 'Ref' का मतलब क्या है। 'Ref' शब्द 'Reference' का short form है। सरल शब्दों में कहें तो, Ref एक ऐसा special window या pointer है जो React को सीधे किसी native DOM element से जोड़ता है।
सामान्य तौर पर, React components के बीच data flow हमेशा unidirectional (एकतरफा) होता है—यानी top to bottom, Props के जरिए। जब भी हमें UI को बदलना होता है, हम State को update करते हैं, जिससे React component re-render होता है और UI बदल जाता है। इसे हम Declarative approach कहते हैं।
लेकिन ज़रा सोचिए, अगर आपको:
- किसी input text-box पर user के button click करते ही focus() ले जाना हो।
- किसी modal popup के बाहर click होने पर उसे close करना हो (Detecting outside clicks)।
- Web Audio/Video APIs (जैसे play, pause) को direct control करना हो।
- किसी element की exact width, height या text scroll position calculate करनी हो।
इन सब कामों के लिए React का standard state system बहुत भारी और slow हो जाता है, क्योंकि हर छोटी manipulation के लिए re-render करना performance के लिहाज से सही नहीं है। ऐसे समय पर हमें Imperative approach की ज़रूरत होती है, और यही वो जगह है जहाँ useRef Hook हमारा तारणहार बनता है!
useRef Hook kya hai aur yeh kaise kaam करता है?
React 16.8 में Hooks के आने के बाद, Functional Components में Refs को handle करने के लिए useRef Hook को introduce किया गया था।
जब आप useRef() को call करते हैं, तो यह आपको एक simple, plain JavaScript object return करता है। इस object में केवल एक key होती है: current.
const myRef = useRef(initialValue);
// myRef returns: { current: initialValue }
ध्यान देने वाली बात ये है कि यह current property mutable होती है। यानी आप इसकी value को कभी भी change कर सकते हैं। इसकी सबसे बड़ी खासियत यह है कि current value के change होने पर आपका component re-render नहीं होता।
🏗️ State vs Ref Render Flow
State Change
→
Re-Trigger Render
→
UI Updates
Ref (.current) Change
→
Persist Value (No Render)
→
Direct DOM Action
Diagram: State updates trigger UI lifecycle, while Ref bypasses rendering for instant DOM or variable mutations.
useRef Hook ka use kaise karein? Step-by-Step Guide
चलिए, अब practical होकर समझते हैं कि इसे अपने code में कैसे implement करना है। हम इसके दो सबसे popular use cases देखेंगे: DOM element को reference करना और render-free mutable variable की तरह use करना।
Step 1: DOM Element को Access करना (Focus Input Example)
मान लीजिए कि आपके पास एक form है और आप चाहते हैं कि जब user page पर आए, तो input automatic active (focus) हो जाए।
- सबसे पहले React library से
useRefको import करें। - अपने component के अंदर
useRef(null)को call करके एक instance create करें। - उस ref variable को HTML elements के
refattribute में pass कर दें। -
useEffectया helper function की मदद सेref.currentको use करके native DOM methods (जैसे .focus()) run करें।
चलिए, इसका complete, clean working code देखते हैं:
import React, { useRef, useEffect } from 'react';
function AutoFocusInput() {
// 1. Ref initialize karein
const inputRef = useRef(null);
useEffect(() => {
// 2. Component mount hone par current element par focus karein
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
const handleButtonClick = () => {
// Buttons click par programmatic action
if (inputRef.current) {
inputRef.current.style.backgroundColor = '#fef08a'; // custom styling
inputRef.current.placeholder = 'Type something awesome!';
}
};
return (
<div style={{ padding: '20px', maxWidth: '400px', margin: 'auto' }}>
<h3>React Input Focus with useRef</h3>
<input
ref={inputRef}
type="text"
placeholder="Waiting for focus..."
style={{ padding: '8px', width: '100%', marginBottom: '10px', borderRadius: '4px', border: '1px solid #ccc' }}
/>
<button
onClick={handleButtonClick}
style={{ padding: '8px 16px', backgroundColor: '#06b6d4', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer' }}
>
Highlight Input
</button>
</div>
);
}
export default AutoFocusInput;
Step 2: Storing Mutable Values (Without Re-rendering)
अक्सर हमें ऐसी variables की ज़रूरत होती है जो multi-render lifecycles के पार अपनी value को याद (persist) रख सकें, लेकिन उनके change होने से user interface दोबारा paint (re-render) न हो। उदाहरण के लिए—एक custom stopwatch/timer का Interval ID store करना!
यहाँ complete dynamic countdown timer का working example है:
import React, { useState, useRef } from 'react';
function StopWatchTimer() {
const [seconds, setSeconds] = useState(0);
// Interval ID ko state me rakhne se component re-render hoga, isliye useRef perfect hai
const timerId = useRef(null);
const startTimer = () => {
if (timerId.current !== null) return; // double click safety
timerId.current = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
};
const stopTimer = () => {
if (timerId.current !== null) {
clearInterval(timerId.current);
timerId.current = null; // Clear persistence references
}
};
const resetTimer = () => {
stopTimer();
setSeconds(0);
};
return (
<div style={{ textAlign: 'center', padding: '30px', border: '1px solid #ddd', borderRadius: '12px', maxWidth: '350px', margin: '20px auto' }}>
<h2 style={{ fontSize: '3rem', margin: '0 0 20px 0' }}>{seconds}s</h2>
<div style={{ display: 'flex', gap: '10px', justifyContent: 'center' }}>
<button onClick={startTimer} style={{ background: '#22c55e', color: 'white', border: 'none', padding: '10px 15px', borderRadius: '6px', cursor: 'pointer' }}>Start</button>
<button onClick={stopTimer} style={{ background: '#ef4444', color: 'white', border: 'none', padding: '10px 15px', borderRadius: '6px', cursor: 'pointer' }}>Stop</button>
<button onClick={resetTimer} style={{ background: '#64748b', color: 'white', border: 'none', padding: '10px 15px', borderRadius: '6px', cursor: 'pointer' }}>Reset</button>
</div>
</div>
);
}
export default StopWatchTimer;
useState vs useRef: Dono me kya difference hai?
दोस्तों, कई developers के मन में यह सवाल आता है कि "अगर हम useState से data store कर ही रहे हैं, तो useRef की क्या ज़रूरत है?" या "useState vs useRef में अंतर क्या है?"
इस doubt को दूर करने के लिए आइए इस comprehensive table को देखते हैं:
| Features | useState Hook | useRef Hook |
|---|---|---|
| Re-trigger Re-render | हाँ, state update होने पर पूरा component re-render होता है। | नहीं, ref.current change होने पर component re-render नहीं होता। |
| Direct DOM Access | नहीं, यह virtual representation पर काम करता है। | हाँ, ref={myRef} के ज़रिए direct access मुमकिन है। |
| Primary Use-case | UI में update दिखाने और dynamically state track करने के लिए। | DOM interactions, intervals tracking, और memory caching के लिए। |
| Sync vs Async Update | Asynchronous (React state batch processing करता है)। | Synchronous (तुरंत value mutate हो जाती है)। |
useRef me hone wali common errors aur unka solution
जब आप React me Refs aur useRef Hook का use करना शुरू करते हैं, तो कुछ common error आ सकती हैं। चलिए बात करते हैं कि सीनियर डेवलपर्स इन errors को कैसे handle और debug करते हैं।
1. Error: "Cannot read properties of null (reading 'focus')"
यह error तब आती है जब आप component के fully mount होने से पहले ही ref.current को access करने की कोशिश करते हैं।
गलत तरीका:
// code crash ho jayega agar DOM create nahi hua hai
const inputRef = useRef(null);
inputRef.current.focus();
सही तरीका: हमेशा render cycle पूरी होने का wait करें (जैसे useEffect में) और optional chaining या null checking का use करें:
useEffect(() => {
// Always verify if current is truthy
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
2. Error: "Function components cannot be given refs"
जब आप किसी functional custom child component पर standard ref pass करने की कोशिश करते हैं, तो React warning throw करता है।
Solution: Custom components सीधे standard ref accept नहीं करते। इसके लिए आपको React.forwardRef API का use करना होगा।
यहाँ forwardRef के साथ child functional component को design करने का method देखें:
import React, { forwardRef, useRef } from 'react';
// Child component wrapped inside forwardRef
const CustomInput = forwardRef((props, ref) => {
return <input ref={ref} type="text" style={{ padding: '8px', border: '2px solid blue' }} {...props} />;
});
function ParentComponent() {
const childRef = useRef(null);
const focusChild = () => {
if (childRef.current) {
childRef.current.focus();
}
};
return (
<div style={{ padding: '20px' }}>
<h4>Forwarding Refs Example</h4>
<CustomInput ref={childRef} placeholder="I am nested child input" />
<button onClick={focusChild} style={{ marginTop: '10px' }}>Focus Child</button>
</div>
);
}
export default ParentComponent;
Production-Ready Best Practices & Performance Optimization Tips
एक senior architect की हैसियत से, मैं आपको कुछ ऐसे tips देना चाहता हूँ जो आपके applications को ultra-fast बनाएंगे और memory leak से बचाएंगे:
- Overuse से बचें: React declarative design पर बना है। बात-बात पर Refs का use करके inline manipulation करना code readability और standards के खिलाफ है। इसका use तभी करें जब declarative logic से काम न चले।
- Cleanup Memory: जब आप refs में setInterval, custom event listeners, या standard libraries (जैसे chart.js, maps) initialize करते हैं, तो component unmount होते समय refs reference cleanup ज़रूर करें।
-
Don't Read/Write ref.current during rendering: Component के pure render body के अंदर
ref.currentको manipulate न करें। यह side-effects का कारण बनता है। हमेशा standard callbacks या execution handlers (जैसेuseEffect) के अंदर ही refs updates करें। - Official Documentation Reference: Refs के patterns के बारे में और detail में जानने के लिए आप official React useRef Hooks Documentation भी consult कर सकते हैं।
तो दोस्तों, हमने आज सीखा कि React me Refs aur useRef Hook क्या हैं, इनके practical use cases क्या हैं, और functional design patterns में state sync के बिना directly mutable elements को smoothly कैसे handle किया जाता है। अब इसे अपने React project में implement कीजिए, codes के साथ experiment कीजिए, और अगर कोई परेशानी आए तो उसे fix error strategies के साथ debug करें!
Frequently Asked Questions (FAQs)
Q1: क्या useRef state की जगह use किया जा सकता है?
नहीं, useRef को state की जगह use नहीं किया जा सकता। useRef data persistence के काम आता है लेकिन इसके change होने पर React screen को re-draw (re-render) नहीं करता। इसलिए अगर आपका data UI updates में reflect होना है, तो आपको standard useState का ही use करना होगा।
Q2: useRef(null) और React.createRef() में क्या अंतर है?
createRef() हमेशा class-based components में use किया जाता है और यह हर single render cycle पर एक नया reference object generate करता है। इसके विपरीत, useRef Hook functional components के लिए optimized है और component lifecycle के हर dynamic update के दौरान identical reference object को persist करके रखता है।
Q3: ref.current की default value null क्यों रखी जाती है?
शुरुआत में जब component process में होता है, तब DOM element generate नहीं हुआ होता। इसलिए initial ref null रखा जाता है। जैसे ही component complete layout draw करके HTML parse करता है, React automatic node reference 'null' की जगह select current DOM node पर map कर देता है।
Q4: क्या useRef dependency lists (useEffect) में re-trigger के काम आता है?
नहीं, useRef component lifecycle triggers के rules को change नहीं करता। चूँकि .current changes re-render trigger नहीं करते, इसलिए React refs changes को monitor नहीं कर पाता। Dependency array में ref variables use करने से elements trigger loop fire नहीं करेंगे।
Q5: useRef memory allocation में high storage consumption करता है क्या?
नहीं, useRef बहुत lightweight wrapper object है। यह memory utilization में generic plain JS references जितना ही memory consumption करता है और component destroy होने पर internal values structural garbage collection flow द्वारा clean कर दी जाती हैं।
Top comments (0)