useRef — ay isang React hook na gumagawa ng mutable ref object na may property na .current, na pinapanatili sa pagitan ng mga render ng component. Hindi tulad ng useState, ang pagbabago ng .current ay hindi nagdudulot ng muling pag-render, na ginagawang perpekto ang useRef para sa pag-iimbak ng mga DOM reference, timer, at anumang mga value na dapat makaligtas sa mga render nang hindi muling iginuguhit ang UI. Ayon sa React Documentation (2025), ang ref object ay nilikha nang isang beses sa buong buhay ng component at hindi nagbabago sa pagitan ng mga render, na ginagarantiyahan ang katatagan ng reference.
Mga pangunahing punto
useRef — ay isang hook na idinagdag sa React 16.8, na nagbabalik ng mutable ref object na may iisang property na .current. Ang paunang halaga ay itinalaga sa .current kapag ni-mount ang component. Ang pangunahing pagkakaiba mula sa isang ordinaryong variable — ang ref object ay nakaligtas sa muling pag-render: sa muling pag-render, hindi muling ginagawa ng React ang ref, kundi ibinabalik ang parehong object.
Ang panloob na implementasyon ng useRef ay gumagamit ng parehong mekanismo ng useState at useEffect — isang naka-link na listahan ng mga hook sa fiber node. Gayunpaman, hindi tulad ng useState, hindi sinusubaybayan ng React ang mga pagbabago ng ref object, hindi nag-queue ng mga update, at hindi nag-iiskedyul ng muling pag-render. Ginagawa nito ang useRef na isang napakagaan na hook na hindi nakakaapekto sa performance kahit na sa madalas na pagbabago.
Ayon sa React Team — Hooks FAQ (2025), ang useRef ay isang “kahon” na nag-iimbak ng halaga. Syntactic sugar: const ref = useRef(initialValue) ay katumbas ng const ref = { current: initialValue } na may pagkakaiba na ginagarantiyahan ng React na ang ref object ay magiging pareho sa bawat render. Walang magic — isang matatag na reference lamang na pinamamahalaan ng React.
import { useRef } from 'react';
function Component() {
const countRef = useRef(0);
// countRef.current = 0 sa una
// countRef.current = 5 pagkatapos ng mutasyon
// Walang nagaganap na muling pag-render!
}
Ang pinakakaraniwang sitwasyon ng paggamit ng useRef — pagkuha ng direktang access sa elemento ng DOM. Itinatalaga ng React ang elementRef.current sa reference ng DOM node pagkatapos i-mount ang component. Ito ay kinakailangan para sa pag-focus ng input, pagsukat ng dimensyon ng elemento, integrasyon sa mga animation library at library na hindi gumagamit ng React rendering.
Awtomatikong pinamamahalaan ng React ang mga ref reference sa DOM: kapag nagmo-mount ay itinatalaga ang aktwal na DOM node, kapag nag-a-unmount ay nirerese (nagiging null). Ginagarantiyahan nito na ang .current ay laging may napapanahong halaga at pinipigilan ang pagtagas ng memorya sa pamamagitan ng “nakabitin” na mga reference sa mga tinanggal na elemento. Walang kinakailangang manual na paglilinis.
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// I-focus ang input pagkatapos i-mount ang component
inputRef.current?.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
Ayon sa React — Refs and DOM documentation (2025), huwag gumamit ng ref para sa mga deklaratibong operasyon — pagbubukas/pagsasara ng mga modal, pamamahala ng visibility. Para sa mga layuning ito ay mayroong state at props. Ang mga ref ay para sa mga imperative na operasyon na hindi maaaring ipahayag nang deklaratibo: focus, pagpili ng text, integrasyon sa mga third-party library.
Ang pangalawang pinakamahalagang sitwasyon — pag-iimbak ng mga arbitraryong halaga na dapat mapanatili sa pagitan ng mga render, ngunit ang pagbabago nito ay hindi dapat magdulot ng muling pag-render. Mga tipikal na halimbawa: mga identifier ng timer (setInterval/setTimeout), mga flag para sa pagkansela ng mga request, mga nakaraang halaga ng props para sa paghahambing, at anumang data na hindi nakakaapekto sa output ng UI.
Ito ay lalong kapaki-pakinabang sa useEffect: iniimbak ng useRef ang identifier ng timer, at nililinis ito ng cleanup. Kung ang timerId ay iniimbak sa useState, ang bawat tawag sa setTimerId ay magdudulot ng hindi kinakailangang muling pag-render na hindi kailangan para sa lohika o sa UI. Nalulutas ng useRef ang problemang ito nang walang overhead at walang hindi kinakailangang muling pagguhit.
function Timer() {
const intervalRef = useRef(null);
const start = () => {
intervalRef.current = setInterval(() => {
console.log('tiktak');
}, 1000);
};
const stop = () => {
clearInterval(intervalRef.current);
};
useEffect(() => stop, []);
return <><button onClick={start}>Start</button><button onClick={stop}>Stop</button></>;
}
Ang pangunahing dilemma — ang pagpili sa pagitan ng useRef at useState — ay nalulutas sa isang tanong: “Kailangan ba ng muling pag-render kapag nagbago ang halaga?”. Kung oo — useState. Kung hindi — useRef. Ang useState ay nag-iimbak ng estado na nakakaapekto sa output ng component; ang useRef ay nag-iimbak ng data na kailangan para sa panloob na lohika, ngunit hindi nakakaapekto sa UI.
Sa pagsasanay, madalas gumagamit ang mga developer ng useRef para mag-imbak ng mga callback, upang maiwasan ang mga problema sa mga closure. Halimbawa, kung ang useEffect ay nag-subscribe sa isang event at sa loob ng callback ay kailangan ang napapanahong state — itago ang callback sa useRef. Sa bawat render, i-update ang ref.current ng bagong function, at ang effect ay palaging tatawag ng sariwang callback nang walang muling pag-subscribe.
| Kriteria | useRef | useState |
|---|---|---|
| Muling pag-render | Hindi nagdudulot sa pagbabago | Nagdudulot sa bawat setState |
| Mutasyon | Direkta: ref.current = value | Sa pamamagitan ng setter: setState(value) |
| Paggamit sa JSX | Hindi ginagamit (walang epekto) | Ginagamit sa output ng component |
| Halimbawa | Mga timer, DOM reference, nakaraang halaga | Data ng form, UI state, mga flag |
Mayroong anti-pattern: paggamit ng useRef upang mag-imbak ng data na kailangan sa JSX, ngunit ang pagbabago nito ay hindi dapat magdulot ng muling pag-render. Ito ay humahantong sa desynchronization — ang UI ay nagpapakita ng lumang data, kahit na ang ref.current ay bago na. Kung ang halaga ay ipinapakita sa UI — gamitin ang useState. Kung ginagamit lamang sa loob ng lohika — useRef.
Ang kombinasyon ng useRef + useEffect — isang karaniwang pattern para sa pagsubaybay ng mga nakaraang halaga ng props. Itago ang nakaraang halaga sa ref, ihambing sa kasalukuyan sa useEffect, at gumawa ng desisyon batay sa pagkakaiba. Ito ay lalong kapaki-pakinabang sa mga animation, kapag kailangan mong malaman kung anong halaga ang bago ang pagbabago.
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>;
}
Ayon sa React Documentation — Hooks FAQ (2025), ang pattern na ito ay tinatawag na “previous value pattern”. Ito ay gumagana dahil pinapanatili ng useRef ang halaga sa pagitan ng mga render, at ang useEffect ay isinasagawa pagkatapos makumpirma ang mga pagbabago. Una, ang DOM ay ina-update ng bagong price, pagkatapos ay inihambing ng useEffect ang nauna (na nasa ref pa) at ina-update ang ref.current sa kasalukuyang halaga.
Ang pinakakaraniwang pagkakamali — pagbabasa ng ref.current sa render phase para sa pagkalkula ng JSX. Dahil ang pagbabago ng ref.current ay hindi nagdudulot ng muling pag-render, ang component ay maaaring gumamit ng lumang halaga. Kung ang halaga ng .current ay lumalahok sa output ng UI — gamitin ang useState. Kung kailangan mong i-synchronize ang ref at state, gamitin ang useEffect para i-update ang state mula sa ref.
// ❌ Huwag basahin ang ref.current sa panahon ng render para sa pagpapakita
function BadComponent() {
const valRef = useRef(0);
return <p>{valRef.current}</p>; // HINDI mag-a-update sa mutasyon
}
// ✅ Gamitin ang state para sa pagpapakita, ref para sa lohika
function GoodComponent() {
const [val, setVal] = useState(0);
const valRef = useRef(0);
return <p>{val}</p>;
}
Ang isa pang karaniwang pagkakamali — paggamit ng useRef bilang tanging paraan ng pag-iimbak ng estado sa component, kapag ang data ay nakakaapekto pa rin sa UI. Pinipili ng mga developer ang useRef upang maiwasan ang “di kailangan” na muling pag-render, ngunit sa huli ay nakakakuha ng UI na hindi nag-a-update. Ang tamang diskarte: gamitin ang useState para sa UI data at useRef lamang para sa mga pantulong na halaga na hindi lumalahok sa render.
Mga madalas itanong
Oo, ito ay isang karaniwang pattern — previous state pattern. Gumawa ng ref at i-update ito sa useEffect sa bawat pagbabago ng sinusubaybayang halaga. Sa sandali sa pagitan ng render at effect, ang ref.current ay naglalaman ng nakaraang halaga na maaaring ihambing sa kasalukuyan. Hindi ito nangangailangan ng karagdagang muling pag-render at gumagana sa lahat ng uri ng data.
Itinatalaga lamang ng React ang ref.current na halaga ng DOM node pagkatapos ma-render ang elemento at maidagdag sa tunay na DOM. Sa unang render, ang component ay hindi pa naka-mount, kaya ang ref.current ay katumbas ng paunang halaga (null). Ang pag-access sa DOM sa pamamagitan ng ref.current ay posible lamang sa useEffect o sa mga event handler na tinatawag pagkatapos ng mounting.
createRef ay gumagawa ng bagong ref object sa bawat render — dapat lamang gamitin sa mga class component. useRef ay gumagawa ng ref nang isang beses at ibinabalik ang parehong object sa lahat ng sumusunod na render. Sa mga functional component, gumamit lamang ng useRef; ang createRef ay magdudulot ng pagkawala ng halaga sa muling pag-render, dahil ang object ay muling gagawin.
Oo, ang ref object ay maaaring ipasa bilang isang ordinaryong prop: <Child inputRef={inputRef} />. Ginagamit ito ng child component sa pamamagitan ng inputRef.current. Gayunpaman, upang direktang ipasa ang ref sa DOM element ng child component, gamitin ang forwardRef — isang HOC na nagpapahintulot sa ref na makapasa sa pamamagitan ng props. Kung walang forwardRef, ang ref ay hindi awtomatikong maiugnay sa DOM element sa loob ng child component.
Ikabit ang ref sa elemento, pagkatapos sa useEffect basahin ang ref.current.getBoundingClientRect() o ref.current.offsetWidth / offsetHeight. Para sa reaktibong pagsubaybay ng mga pagbabago sa laki, gamitin ang ResizeObserver sa loob ng useEffect: gumawa ng observer, mag-subscribe sa mga pagbabago, at i-update ang state ng mga bagong dimensyon. Huwag kalimutang i-disable ang observer sa cleanup.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din