useRef — bu React hooki bo'lib, .current xususiyatiga ega mutatsiya qilinadigan ref obyektini yaratadi va komponent renderlari orasida saqlanadi. useState dan farqli o'laroq, .current ning o'zgarishi qayta renderlashga olib kelmaydi, bu useRef ni DOM havolalari, taymerlar va UI ni qayta chizmasdan renderlarni o'tkazib yuborishi kerak bo'lgan har qanday qiymatlarni saqlash uchun ideal qiladi. React Documentation (2025) ga ko'ra, ref obyekti komponentning umri davomida bir marta yaratiladi va renderlar orasida o'zgarmaydi, bu havolaning barqarorligini kafolatlaydi.
Asosiy fikrlar
useRef — React 16.8 da qo'shilgan, bitta .current xususiyatiga ega mutatsiya qilinadigan ref obyektini qaytaruvchi hook. Boshlang'ich qiymat komponent o'rnatilganda .current ga tayinlanadi. Oddiy o'zgaruvchidan asosiy farqi — ref obyekti qayta renderlardan omon qoladi: qayta renderlashda React ref ni qayta yaratmaydi, balki o'sha obyektni qaytaradi.
useRef ning ichki implementatsiyasi useState va useEffect bilan bir xil mexanizmdan — fiber tugunidagi bog'langan hooklar ro'yxatidan foydalanadi. Biroq, useState dan farqli o'laroq, React ref obyektining o'zgarishlarini kuzatmaydi, yangilanishlarni navbatga qo'ymaydi va qayta renderlashni rejalashtirmaydi. Bu useRef ni hatte tez-tez o'zgarishlarda ham ishlashga ta'sir qilmaydigan juda yengil hook qiladi.
React Team — Hooks FAQ (2025) ga ko'ra, useRef asosan qiymatni saqlaydigan “quti”dir. Sintaktik shakar: const ref = useRef(initialValue) const ref = { current: initialValue } bilan ekvivalentdir, farqi shundaki React har bir renderda ref obyekti bir xil bo'lishini kafolatlaydi. Hech qanday sehr — shunchaki React tomonidan boshqariladigan barqaror havola.
import { useRef } from 'react';
function Component() {
const countRef = useRef(0);
// countRef.current = 0 boshlang'ich
// countRef.current = 5 mutatsiyadan so'ng
// Qayta render sodir bo'lmaydi!
}
useRef ning eng keng tarqalgan foydalanish stsenariysi — DOM elementiga to'g'ridan-to'g'ri kirish olishdir. React komponent o'rnatilgandan so'ng elementRef.current ni DOM tuguniga havola bilan tayinlaydi. Bu input ga fokus berish, element o'lchamlarini o'lchash, animatsiya kutubxonalari va React renderidan foydalanmaydigan kutubxonalar bilan integratsiya uchun zarur.
React DOM ga ref havolalarini avtomatik boshqaradi: o'rnatishda haqiqiy DOM tugunini tayinlaydi, o'chirishda uni nollaydi (null qiladi). Bu .current da har doim dolzarb qiymat bo'lishini kafolatlaydi va o'chirilgan elementlarga “osilgan” havolalar orqali xotira oqishining oldini oladi. Hech qanday qo'lda tozalash talab qilinmaydi.
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Komponent o'rnatilgandan so'ng input ga fokuslash
inputRef.current?.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
React — Refs and DOM documentation (2025) ga ko'ra, ref ni deklarativ operatsiyalar uchun ishlatmang — modallarni ochish/yopish, ko'rinishni boshqarish. Bu maqsadlar uchun state va proplar mavjud. Reflar imperativ operatsiyalar uchun mo'ljallangan: fokus, matn tanlash, uchinchi tomon kutubxonalari bilan integratsiya.
Ahamiyati bo'yicha ikkinchi stsenariy — ixtiyoriy qiymatlarni saqlash, ular renderlar orasida saqlanishi kerak, lekin ularning o'zgarishi qayta renderlashga olib kelmasligi kerak. Oddiy misollar: taymer identifikatorlari (setInterval/setTimeout), so'rovlarni bekor qilish uchun bayroqlar, solishtirish uchun oldingi prop qiymatlari va UI chiqishiga ta'sir qilmaydigan har qanday ma'lumotlar.
Bu, ayniqsa, useEffect da foydali: useRef taymer identifikatorini saqlaydi, cleanup esa uni tozalaydi. Agar timerId useState da saqlansa, har bir setTimerId chaqiruvi na logika, na UI uchun kerak bo'lmagan qo'shimcha qayta renderlashga olib keladi. useRef bu muammoni overheadsiz va keraksiz qayta chizishlarsiz hal qiladi.
function Timer() {
const intervalRef = useRef(null);
const start = () => {
intervalRef.current = setInterval(() => {
console.log('tiq');
}, 1000);
};
const stop = () => {
clearInterval(intervalRef.current);
};
useEffect(() => stop, []);
return <><button onClick={start}>Start</button><button onClick={stop}>Stop</button></>;
}
Asosiy dilemma — useRef va useState o'rtasidagi tanlov — bitta savol bilan hal qilinadi: “Qiymat o'zgarganda qayta renderlash kerakmi?”. Ha bo'lsa — useState. Yo'q bo'lsa — useRef. useState komponent chiqishiga ta'sir qiluvchi holatni saqlaydi; useRef ichki mantiq uchun kerakli, ammo UI ga ta'sir qilmaydigan ma'lumotlarni saqlaydi.
Amalda, dasturchilar yopilish muammolaridan qochish uchun tez-tez useRef dan callbacklarni saqlashda foydalanadilar. Masalan, agar useEffect hodisaga obuna bo'lsa va callback ichida dolzarb state kerak bo'lsa — callback ni useRef da saqlang. Har bir renderda ref.current ni yangi funksiya bilan yangilang va effekt qayta obuna bo'lmasdan har doim yangi callback ni chaqiradi.
| Mezon | useRef | useState |
|---|---|---|
| Qayta render | O'zgarishda chaqirmaydi | Har bir setState da chaqiradi |
| Mutatsiya | To'g'ridan-to'g'ri: ref.current = value | Setter orqali: setState(value) |
| JSX da ishlatish | Ishlatilmaydi (effekti yo'q) | Komponent chiqishida ishlatiladi |
| Misol | Taymerlar, DOM havolalari, oldingi qiymatlar | Forma ma'lumotlari, UI holati, bayroqlar |
Anti-namuna mavjud: JSX da kerak bo'lgan, ammo o'zgarishi qayta renderlashga olib kelmasligi kerak bo'lgan ma'lumotlarni saqlash uchun useRef dan foydalanish. Bu desinxronizatsiyaga olib keladi — UI eski ma'lumotlarni ko'rsatadi, holbuki ref.current allaqachon yangi. Agar qiymat UI da ko'rsatilsa — useState dan foydalaning. Faqat mantiq ichida ishlatilsa — useRef.
useRef + useEffect birikmasi — proplarning oldingi qiymatlarini kuzatish uchun standart na'munadir. Oldingi qiymatni ref da saqlang, useEffect da joriy bilan solishtiring va farq asosida qaror qabul qiling. Bu, ayniqsa, animatsiyalarda, o'zgarishdan oldin qanday qiymat bo'lganini bilish kerak bo'lganda foydali.
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 Documentation — Hooks FAQ (2025) ga ko'ra, bu na'muna “previous value pattern” deb ataladi. U ishlaydi, chunki useRef qiymatni renderlar orasida saqlaydi, useEffect esa o'zgarishlar tasdiqlangandan so'ng bajariladi. Avval DOM yangi price bilan yangilanadi, so'ng useEffect oldingi bilan (hali ref da) solishtiradi va ref.current ni joriy qiymatga yangilaydi.
Eng keng tarqalgan xato — ref.current ni render fazasida o'qish JSX ni hisoblash uchun. ref.current o'zgarishi qayta renderlashga olib kelmagani sababli, komponent eskirgan qiymatdan foydalanishi mumkin. Agar .current qiymati UI chiqishida ishtirok etsa — useState dan foydalaning. Agar ref va state ni sinxronlashtirish kerak bo'lsa, state ni ref dan yangilash uchun useEffect dan foydalaning.
// ❌ Render vaqtida ref.current ni ko'rsatish uchun o'qimang
function BadComponent() {
const valRef = useRef(0);
return <p>{valRef.current}</p>; // mutatsiyada YANGILANMAYDI
}
// ✅ Ko'rsatish uchun state, mantiq uchun ref dan foydalaning
function GoodComponent() {
const [val, setVal] = useState(0);
const valRef = useRef(0);
return <p>{val}</p>;
}
Yana bir keng tarqalgan xato — ma'lumotlar UI ga ta'sir qilgan holda, useRef ni komponentda holatni saqlashning yagona usuli sifatida ishlatish. Dasturchilar “keraksiz” qayta renderlardan qochish uchun useRef ni tanlaydilar, ammo natijada yangilanmaydigan UI olishadi. To'g'ri yondashuv: UI ma'lumotlari uchun useState dan va faqat renderda ishtirok etmaydigan yordamchi qiymatlar uchun useRef dan foydalaning.
Tez-tez beriladigan savollar
Ha, bu keng tarqalgan na'muna — previous state pattern. Ref yarating va uni useEffect da kuzatilayotgan qiymatning har bir o'zgarishida yangilang. Render va effekt orasidagi momentda ref.current solishtirish mumkin bo'lgan oldingi qiymatni o'z ichiga oladi. Bu qo'shimcha qayta renderlarni talab qilmaydi va har qanday ma'lumot turlari bilan ishlaydi.
React ref.current ga DOM tugunining qiymatini faqat element render qilingan va real DOM ga qo'shilganidan so'ng tayinlaydi. Birinchi render paytida komponent hali o'rnatilmagan, shuning uchun ref.current boshlang'ich qiymatga (null) teng. DOM ga ref.current orqali kirish faqat useEffect da yoki o'rnatilgandan so'ng chaqiriladigan hodisa handlerlarida mumkin.
createRef har bir renderda yangi ref obyektini yaratadi — uni faqat sinf komponentlarida ishlatish kerak. useRef ref ni bir marta yaratadi va barcha keyingi renderlarda bir xil obyektni qaytaradi. Funksional komponentlarda faqat useRef dan foydalaning; createRef qayta renderda obyekt qayta yaratilgani sababli qiymat yo'qolishiga olib keladi.
Ha, ref obyekti oddiy prop sifatida uzatilishi mumkin: <Child inputRef={inputRef} />. Bola komponent uni inputRef.current orqali ishlatadi. Biroq, ref ni to'g'ridan-to'g'ri bola komponentning DOM elementiga uzatish uchun forwardRef — ref ni proplar orqali o'tkazishga imkon beruvchi HOC dan foydalaning. forwardRef bo'lmasa, ref avtomatik ravishda bola komponent ichidagi DOM elementiga bog'lanmaydi.
Ref ni elementga bog'lang, so'ng useEffect da ref.current.getBoundingClientRect() yoki ref.current.offsetWidth / offsetHeight ni o'qing. O'lcham o'zgarishlarini reaktiv kuzatish uchun useEffect ichida ResizeObserver dan foydalaning: observer yarating, o'zgarishlarga obuna bo'ling va state ni yangi o'lchamlar bilan yangilang. Observer ni cleanup da o'chirishni unutmang.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.