useRef एक React हुक है जो .current प्रॉपर्टी के साथ एक म्यूटेबल ref ऑब्जेक्ट बनाता है, जो कंपोनेंट के रेंडर के बीच संरक्षित रहता है। useState के विपरीत, .current को बदलने से री-रेंडर नहीं होता, जो useRef को DOM संदर्भ, टाइमर और किसी भी मान को स्टोर करने के लिए आदर्श बनाता है जिसे UI को पुनः रेंडर किए बिना रेंडर के बीच बनाए रखना होता है। React दस्तावेज़ीकरण (2025) के अनुसार, ref ऑब्जेक्ट कंपोनेंट के जीवनकाल में एक बार बनता है और रेंडर के बीच नहीं बदलता, जो संदर्भ की स्थिरता सुनिश्चित करता है।
मुख्य बिंदु
useRef एक हुक है जो React 16.8 में जोड़ा गया था जो एकल .current प्रॉपर्टी के साथ एक म्यूटेबल ref ऑब्जेक्ट लौटाता है। प्रारंभिक मान कंपोनेंट माउंट होने पर .current को असाइन किया जाता है। सामान्य चर से मुख्य अंतर यह है कि ref ऑब्जेक्ट री-रेंडर से बच जाता है: बाद के रेंडर में React ref को पुनः नहीं बनाता बल्कि वही ऑब्जेक्ट लौटाता है।
आंतरिक रूप से, useRef वही तंत्र उपयोग करता है जो useState और useEffect — fiber-नोड पर हुक की linked list। हालाँकि, useState के विपरीत, React ref ऑब्जेक्ट के परिवर्तनों को ट्रैक नहीं करता, अपडेट को कतारबद्ध नहीं करता और री-रेंडर शेड्यूल नहीं करता। यह useRef को एक अत्यधिक हल्का हुक बनाता है जो बार-बार परिवर्तनों पर भी प्रदर्शन को प्रभावित नहीं करता।
React टीम — Hooks FAQ (2025) के अनुसार, useRef मूल रूप से एक «बक्सा» है जो मान संग्रहीत करता है। सिंटैक्टिक शुगर: const ref = useRef(प्रारंभिक_मान) const ref = { current: प्रारंभिक_मान } के बराबर है, इस अंतर के साथ कि React गारंटी देता है कि ref ऑब्जेक्ट हर रेंडर पर वही होगा। कोई जादू नहीं — बस React द्वारा प्रबंधित एक स्थिर संदर्भ।
import { useRef } from 'react';
function Component() {
const countRef = useRef(0);
// countRef.current = 0 प्रारंभ में
// countRef.current = 5 परिवर्तन के बाद
// कोई री-रेंडर नहीं होता!
}
useRef का सबसे सामान्य उपयोग किसी DOM तत्व तक सीधी पहुँच प्राप्त करना है। React कंपोनेंट माउंट होने के बाद elementRef.current को DOM नोड का संदर्भ निर्दिष्ट करता है। यह इनपुट को फोकस करने, तत्व के आयाम मापने, एनिमेशन लाइब्रेरी और उन लाइब्रेरी के साथ एकीकरण के लिए आवश्यक है जो React रेंडरिंग का उपयोग नहीं करतीं।
React स्वचालित रूप से DOM पर ref संदर्भ प्रबंधित करता है: माउंट होने पर वास्तविक DOM नोड निर्दिष्ट करता है, अनमाउंट होने पर null कर देता है। यह गारंटी देता है कि .current में हमेशा नवीनतम मान हो और हटाए गए तत्वों के लटकते संदर्भों के माध्यम से मेमोरी लीक को रोकता है। किसी मैन्युअल सफाई की आवश्यकता नहीं है।
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// कंपोनेंट माउंट होने के बाद इनपुट फोकस करें
inputRef.current?.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
React — Refs और DOM दस्तावेज़ीकरण (2025) के अनुसार, घोषणात्मक संचालन — मोडल खोलना/बंद करना, दृश्यता प्रबंधित करना — के लिए ref का उपयोग न करें। इन उद्देश्यों के लिए state और props हैं। Refs उन अनिवार्य संचालनों के लिए हैं जिन्हें घोषणात्मक रूप से व्यक्त नहीं किया जा सकता: फोकस, टेक्स्ट चयन, तृतीय-पक्ष लाइब्रेरी के साथ एकीकरण।
दूसरा सबसे महत्वपूर्ण उपयोग है मनमाना मान संग्रहीत करना जो रेंडर के बीच बने रहने चाहिए लेकिन जिनके परिवर्तन से री-रेंडर नहीं होना चाहिए। विशिष्ट उदाहरण: टाइमर पहचानकर्ता (setInterval/setTimeout), अनुरोध रद्द करने के फ़्लैग, तुलना के लिए पिछले prop मान और कोई भी डेटा जो UI आउटपुट को प्रभावित नहीं करता।
यह विशेष रूप से useEffect में उपयोगी है: useRef टाइमर पहचानकर्ता संग्रहीत करता है और cleanup उसे साफ़ करता है। यदि timerId को useState में संग्रहीत किया जाता, तो प्रत्येक setTimerId कॉल एक अनावश्यक री-रेंडर का कारण बनता जो न तो तर्क के लिए और न ही UI के लिए आवश्यक है। useRef इस समस्या को बिना ओवरहेड और अनावश्यक री-रेंडर के हल करता है।
function Timer() {
const intervalRef = useRef(null);
const start = () => {
intervalRef.current = setInterval(() => {
console.log('टिक');
}, 1000);
};
const stop = () => {
clearInterval(intervalRef.current);
};
useEffect(() => stop, []);
return <><button onClick={start}>Start</button><button onClick={stop}>Stop</button></>;
}
मुख्य दुविधा — useRef और useState के बीच चयन — एक प्रश्न से हल होती है: «क्या मान बदलने पर री-रेंडर आवश्यक है?» यदि हाँ — useState. यदि नहीं — useRef. useState उस स्थिति को संग्रहीत करता है जो कंपोनेंट आउटपुट को प्रभावित करती है; useRef आंतरिक तर्क के लिए आवश्यक डेटा संग्रहीत करता है लेकिन UI को प्रभावित नहीं करता।
व्यवहार में, डेवलपर अक्सर क्लोज़र समस्याओं से बचने के लिए कॉलबैक संग्रहीत करने हेतु useRef का उपयोग करते हैं। उदाहरण के लिए, यदि useEffect किसी ईवेंट की सदस्यता लेता है और कॉलबैक को वर्तमान state की आवश्यकता है — कॉलबैक को useRef में संग्रहीत करें। प्रत्येक रेंडर पर, ref.current को एक नए फ़ंक्शन के साथ अपडेट करें, और प्रभाव हमेशा पुनः सदस्यता लिए बिना ताज़ा कॉलबैक को आमंत्रित करेगा।
| मापदंड | useRef | useState |
|---|---|---|
| री-रेंडर | परिवर्तन पर ट्रिगर नहीं होता | प्रत्येक setState पर ट्रिगर होता है |
| परिवर्तन | सीधा: ref.current = मान | सेटर के माध्यम से: setState(मान) |
| JSX में उपयोग | उपयोग नहीं किया जाता (कोई प्रभाव नहीं) | कंपोनेंट आउटपुट में उपयोग किया जाता है |
| उदाहरण | टाइमर, DOM संदर्भ, पिछले मान | फ़ॉर्म डेटा, UI स्थिति, फ़्लैग |
एक एंटी-पैटर्न है: JSX में आवश्यक डेटा के लिए useRef का उपयोग करना जिसके परिवर्तन से री-रेंडर नहीं होना चाहिए। इससे डीसिंक्रनाइज़ेशन होता है — UI पुराना डेटा दिखाता है जबकि ref.current पहले से नया है। यदि मान UI में प्रदर्शित होता है — useState का उपयोग करें। यदि केवल आंतरिक रूप से उपयोग किया जाता है — useRef.
useRef + useEffect का संयोजन पिछले prop मानों को ट्रैक करने का मानक पैटर्न है। पिछले मान को ref में संग्रहीत करें, useEffect में वर्तमान मान से तुलना करें और अंतर के आधार पर निर्णय लें। यह एनिमेशन में विशेष रूप से उपयोगी है जब आपको यह जानने की आवश्यकता होती है कि परिवर्तन से पहले मान क्या था।
function PriceDisplay({ price }) {
const prevPriceRef = useRef(price);
useEffect(() => {
const prevPrice = prevPriceRef.current;
if (price > prevPrice) {
animateUp();
} else if (price < prevPrice) {
animateDown();
}
prevPriceRef.current = price;
}, [price]);
return <span>${price}</span>;
}
React दस्तावेज़ीकरण — Hooks FAQ (2025) के अनुसार, इस पैटर्न को «पिछला मान पैटर्न» कहा जाता है। यह इसलिए काम करता है क्योंकि useRef मान को रेंडर के बीच संरक्षित रखता है, और useEffect परिवर्तन प्रतिबद्ध होने के बाद निष्पादित होता है। पहले DOM नई कीमत के साथ अपडेट होता है, फिर useEffect इसकी तुलना पिछले मान (जो अभी भी ref में है) से करता है और ref.current को वर्तमान मान में अपडेट करता है।
सबसे आम गलती JSX की गणना के लिए रेंडर चरण में ref.current पढ़ना है। चूँकि ref.current बदलने से री-रेंडर नहीं होता, कंपोनेंट पुराने मान का उपयोग कर सकता है। यदि .current UI आउटपुट में भाग लेता है — useState का उपयोग करें। यदि आपको ref और state को सिंक करने की आवश्यकता है, तो ref से state को अपडेट करने के लिए useEffect का उपयोग करें।
// ❌ प्रदर्शन के लिए रेंडर के दौरान ref.current न पढ़ें
function BadComponent() {
const valRef = useRef(0);
return <p>{valRef.current}</p>; // परिवर्तन पर अपडेट नहीं होगा
}
// ✅ प्रदर्शन के लिए state, तर्क के लिए ref का उपयोग करें
function GoodComponent() {
const [val, setVal] = useState(0);
const valRef = useRef(0);
return <p>{val}</p>;
}
एक और सामान्य गलती किसी कंपोनेंट में स्थिति संग्रहीत करने के एकमात्र तरीके के रूप में useRef का उपयोग करना है जब डेटा वास्तव में UI को प्रभावित करता है। डेवलपर «अनावश्यक» री-रेंडर से बचने के लिए useRef चुनते हैं, लेकिन अंततः उन्हें एक ऐसा UI मिलता है जो अपडेट नहीं होता। सही दृष्टिकोण: UI डेटा के लिए useState का उपयोग करें और केवल सहायक मानों के लिए useRef जो रेंडरिंग में भाग नहीं लेते।
अक्सर पूछे जाने वाले प्रश्न
हाँ, यह एक सामान्य पैटर्न है — पिछली स्थिति पैटर्न। एक ref बनाएँ और ट्रैक किए गए मान में प्रत्येक परिवर्तन पर इसे useEffect में अपडेट करें। रेंडर और प्रभाव के बीच, ref.current में पिछला मान होता है, जिसकी तुलना वर्तमान से की जा सकती है। इसमें अतिरिक्त री-रेंडर की आवश्यकता नहीं होती और यह किसी भी डेटा प्रकार के साथ काम करता है।
React तत्व के रेंडर होने और वास्तविक DOM में जोड़े जाने के बाद ही ref.current को DOM नोड का मान निर्दिष्ट करता है। पहले रेंडर के दौरान कंपोनेंट अभी तक माउंट नहीं हुआ है, इसलिए ref.current प्रारंभिक मान (null) के बराबर है। ref.current के माध्यम से DOM तक पहुँच केवल useEffect या ईवेंट हैंडलर में संभव है जो माउंटिंग के बाद बुलाए जाते हैं।
createRef प्रत्येक रेंडर पर एक नया ref ऑब्जेक्ट बनाता है — इसका उपयोग केवल क्लास कंपोनेंट में किया जाना चाहिए। useRef ref को एक बार बनाता है और सभी बाद के रेंडर पर वही ऑब्जेक्ट लौटाता है। फ़ंक्शनल कंपोनेंट में केवल useRef का उपयोग करें; createRef री-रेंडर पर मान खोने का कारण बनेगा क्योंकि ऑब्जेक्ट पुनः बनाया जाएगा।
हाँ, ref ऑब्जेक्ट को सामान्य prop के रूप में पास किया जा सकता है: <Child inputRef={inputRef} />। चाइल्ड कंपोनेंट इसे inputRef.current के माध्यम से उपयोग करता है। हालाँकि, ref को सीधे चाइल्ड कंपोनेंट के DOM तत्व में पास करने के लिए, forwardRef का उपयोग करें — एक HOC जो props के माध्यम से ref को अग्रेषित करने की अनुमति देता है। forwardRef के बिना, ref चाइल्ड कंपोनेंट के अंदर DOM तत्व से स्वचालित रूप से जुड़ा नहीं होगा।
तत्व पर ref बाँधें, फिर useEffect में ref.current.getBoundingClientRect() या ref.current.offsetWidth / offsetHeight पढ़ें। आकार परिवर्तनों की प्रतिक्रियाशील ट्रैकिंग के लिए, useEffect के अंदर ResizeObserver का उपयोग करें: एक observer बनाएँ, परिवर्तनों की सदस्यता लें और नए आयामों के साथ state अपडेट करें। cleanup में observer को डिस्कनेक्ट करना न भूलें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें