useRef — шта је то, хук референци и рад са DOM у React

Аутор: IT Sectr Објављено: 2026-07-04 Време читања: 9 мин

useRef — је React хук који креира мутабилни реф објекат са својством .current, који се чува између рендеровања компоненте. За разлику од useState, промена .current не изазива поновно рендеровање, што чини useRef идеалним за чување DOM референци, тајмера и било којих вредности које треба да преживе рендеровање без поновног исцртавања UI. Према React Documentation (2025), реф објекат се креира једном током живота компоненте и не мења се између рендеровања, што гарантује стабилност референце.

Главне тачке

  • useRef — хук за креирање мутабилног реф објекта са пољем .current.
  • Без поновног рендеровања — промена .current не изазива поновно исцртавање компоненте.
  • DOM референце — преноси се у ref проп елемента за директан приступ DOM чвору.
  • Чување вредности — погодан за тајмере, претходне вредности и било које податке између рендеровања.
  • Стабилна референца — реф објекат се не мења између рендеровања, за разлику од затварања.

Шта је useRef у React

useRef — је хук додат у React 16.8, који враћа мутабилни реф објекат са једним својством .current. Почетна вредност се додељује .current приликом монтирања компоненте. Главна разлика у односу на обичну променљиву — реф објекат преживљава поновна рендеровања: при поновном рендеровању, React не креира поново реф, већ враћа исти објекат.

Унутрашња имплементација useRef користи исти механизам као useState и useEffect — повезану листу хукова на fiber чвору. Међутим, за разлику од useState, React не прати промене реф објекта, не ставља ажурирања у ред и не планира поновно рендеровање. Ово чини useRef изузетно лаганим хуком који не утиче на перформансе чак ни при честим променама.

Према React Team — Hooks FAQ (2025), useRef је у суштини „кутија“ која чува вредност. Синтаксни шећер: const ref = useRef(initialValue) је еквивалентно const ref = { current: initialValue } с тим што React гарантује да ће реф објекат бити исти при сваком рендеровању. Без магије — само стабилна референца којом управља React.

jsx
import { useRef } from 'react';

function Component() {
    const countRef = useRef(0);
    // countRef.current = 0 почетно
    // countRef.current = 5 после мутације
    // Нема поновног рендеровања!
}

Приступ DOM елементима путем useRef

Најчешћи сценариј коришћења useRef — добијање директног приступа DOM елементу. React додељује elementRef.current референцу на DOM чвор након монтирања компоненте. Ово је неопходно за фокусирање input-а, мерење димензија елемента, интеграцију са библиотекама за анимације и библиотекама које не користе React рендеровање.

React аутоматски управља реф референцама на DOM: при монтирању додељује стварни DOM чвор, при демонтирању га ресетује (поставља null). Ово гарантује да је у .current увек ажурна вредност и спречава цурење меморије кроз „висеће“ референце на обрисане елементе. Није потребно ручно чишћење.

jsx
function AutoFocusInput() {
    const inputRef = useRef(null);

    useEffect(() => {
        // Фокусирај input након монтирања компоненте
        inputRef.current?.focus();
    }, []);

    return <input ref={inputRef} type="text" />;
}

Према React — Refs and DOM documentation (2025), не користи ref за декларативне операције — отварање/затварање модала, управљање видљивошћу. У те сврхе постоје state и props. Ref-ови су намењени за императивне операције које се не могу изразити декларативно: фокус, селекција текста, интеграција са библиотекама трећих страна.

Чување мутабилних вредности без поновног рендеровања

Други по важности сценариј — чување произвољних вредности које треба да се сачувају између рендеровања, али чија промена не би требало да изазове поновно рендеровање. Типични примери: идентификатори тајмера (setInterval/setTimeout), заставице за отказивање захтева, претходне вредности пропсова за поређење и сви подаци који не утичу на излаз UI.

Ово је посебно корисно у useEffect: useRef чува идентификатор тајмера, а cleanup га чисти. Ако се timerId чува у useState, сваки позив setTimerId би изазвао непотребно поновно рендеровање које није потребно ни за логику ни за UI. useRef решава овај проблем без overhead-а и без непотребних прецртавања.

jsx
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: када шта користити

Главна дилема — избор између useRef и useState — решава се једним питањем: „Да ли је потребно поновно рендеровање при промени вредности?“. Ако да — useState. Ако не — useRef. useState чува стање које утиче на излаз компоненте; useRef чува податке потребне за унутрашњу логику, али не утиче на UI.

У пракси, програмери често користе useRef за чување callback-ова како би избегли проблеме са затварањима. На пример, ако useEffect претплаћује на догађај и унутар callback-а је потребно ажурно state — чувај callback у useRef. При сваком рендеровању ажурирај ref.current новом функцијом, а ефекат ће увек позивати свеж callback без поновне претплате.

КритеријумuseRefuseState
Поновно рендеровањеНе изазива при промениИзазива при сваком setState
МутацијаДиректна: ref.current = valueПреко setter-а: setState(value)
Коришћење у JSXНе користи се (без ефекта)Користи се у излазу компоненте
ПримерТајмери, DOM референце, претходне вредностиПодаци форме, UI стање, заставице

Постоји анти-шаблон: коришћење useRef за чување података који су потребни у JSX, али чија промена не би требало да изазове поновно рендеровање. То доводи до десинхронизације — UI приказује старе податке, иако је ref.current већ нов. Ако се вредност приказује у UI — користи useState. Ако се користи само унутар логике — useRef.

useRef у комбинацији са useEffect

Комбинација useRef + useEffect — стандардни шаблон за праћење претходних вредности пропсова. Чувај претходну вредност у ref, упореди је са тренутном у useEffect и донеси одлуку на основу разлике. Ово је посебно корисно код анимација, када треба знати која је вредност била пре промене.

jsx
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), овај шаблон се назива „previous value pattern“. Функционише јер useRef чува вредност између рендеровања, а useEffect се извршава након потврде промена. Прво се DOM ажурира новим price, затим useEffect упоређује са претходним (који је још увек у ref) и ажурира ref.current на тренутну вредност.

Типичне грешке са useRef

Најчешћа грешка — читање ref.current у фази рендеровања за израчунавање JSX-а. Пошто промена ref.current не изазива поновно рендеровање, компонента може користити застарелу вредност. Ако вредност .current учествује у излазу UI — користи useState. Ако треба да синхронизујеш ref и state, користи useEffect за ажурирање state-а из ref-а.

  • Ref у JSX — читање ref.current унутар функције рендеровања доводи до десинхронизације UI и података.
  • Ref као зависност useEffect — ref.current не би требало да буде у низу зависности; React не прати његове промене.
  • Заборављена null провера — при демонтирању ref.current постаје null; провери пре приступа.
  • Чување функција у ref — ажурирај ref.current при сваком рендеровању ако користиш шаблон са свежим callback-ом.
jsx
// ❌ Не читај 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 који се не ажурира. Правилан приступ: користи useState за UI податке и useRef само за помоћне вредности које не учествују у рендеровању.

Често постављана питања

Може ли се useRef користити за чување претходног стања?

Да, ово је уобичајен шаблон — previous state pattern. Направи ref и ажурирај га у useEffect при свакој промени праћене вредности. У тренутку између рендеровања и ефекта, ref.current садржи претходну вредност која се може упоредити са тренутном. Ово не захтева додатна поновна рендеровања и ради са било којим типовима података.

Зашто је ref.current null при првом рендеровању?

React додељује ref.current вредност DOM чвора тек након што је елемент рендерован и додат у стварни DOM. Током првог рендеровања, компонента још није монтирана, зато је ref.current једнак почетној вредности (null). Приступ DOM-у преко ref.current могућ је само у useEffect или у handler-има догађаја који се позивају након монтирања.

Која је разлика између useRef и createRef?

createRef креира нови реф објекат при сваком рендеровању — треба га користити само у класним компонентама. useRef креира ref једном и враћа исти објекат при свим наредним рендеровањима. У функционалним компонентама користи искључиво useRef; createRef ће довести до губитка вредности при поновном рендеровању, јер ће објекат бити поново креиран.

Може ли се useRef преносити кроз props?

Да, реф објекат се може пренети као обичан prop: <Child inputRef={inputRef} />. Дете компонента га користи преко inputRef.current. Међутим, за пренос ref-а директно на DOM елемент дете компоненте користи forwardRef — HOC који омогућава преношење ref-а кроз props. Без forwardRef, ref неће бити аутоматски повезан са DOM елементом унутар дете компоненте.

Како измерити димензију елемента помоћу useRef?

Прикачи ref на елемент, затим у useEffect читај ref.current.getBoundingClientRect() или ref.current.offsetWidth / offsetHeight. За реактивно праћење промена величине користи ResizeObserver унутар useEffect: креирај observer, претплати се на промене и ажурирај state новим димензијама. Не заборави да искључиш observer у cleanup-у.

Резиме

  • useRef — хук за креирање мутабилног реф објекта, који се чува између рендеровања без изазивања поновног рендеровања.
  • DOM приступ — ref проп се преноси елементу за директан приступ DOM чвору; доступан након монтирања.
  • Чување података — тајмери, callback-ови, заставице и све вредности које не утичу на UI чувај у ref.
  • useRef наспрам useState — бирај useState ако промена треба да прецрта UI; useRef — ако не.
  • Previous value pattern — чувај претходну вредност у ref, ажурирај у useEffect за поређење.
  • Ref у JSX — не читај ref.current у фази рендеровања; то доводи до десинхронизације UI и података.
  • forwardRef — користи за преношење ref-а кроз props у дете компоненту.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође