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 — ফাইবার-নোডে হুকের লিংকড লিস্ট। তবে, 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-এর মাধ্যমে ব্যবহার করে। তবে, সরাসরি চাইল্ড কম্পোনেন্টের DOM এলিমেন্টে ref পাঠাতে, 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন