useRef — co to je, referenční hook a práce s DOM v Reactu

Autor: IT Sectr Publikováno: 2026-07-04 Doba čtení: 9 min

useRef — je React hook, který vytváří mutovatelný ref objekt s vlastností .current, který je zachován mezi rendery komponenty. Na rozdíl od useState, změna .current nezpůsobuje opětovné vykreslení, což činí useRef ideálním pro ukládání DOM referencí, timerů a jakýchkoli hodnot, které musí přežít rendery bez překreslování UI. Podle React Documentation (2025) je ref objekt vytvořen jednou za dobu života komponenty a nemění se mezi rendery, což zaručuje stabilitu reference.

Hlavní body

  • useRef — hook pro vytvoření mutovatelného ref objektu s polem .current.
  • Žádné opětovné vykreslení — změna .current nezpůsobuje překreslení komponenty.
  • DOM reference — předává se do ref prop elementu pro přímý přístup k DOM uzlu.
  • Ukládání hodnot — vhodné pro timery, předchozí hodnoty a jakákoli data mezi rendery.
  • Stabilní reference — ref objekt se mezi rendery nemění, na rozdíl od uzávěrů.

Co je useRef v Reactu

useRef — je hook přidaný v React 16.8, který vrací mutovatelný ref objekt s jedinou vlastností .current. Počáteční hodnota je přiřazena .current při připojení (mount) komponenty. Hlavní rozdíl oproti běžné proměnné — ref objekt přežije opětovné vykreslení: při opětovném vykreslení React ref znovu nevytváří, ale vrací stejný objekt.

Vnitřní implementace useRef používá stejný mechanismus jako useState a useEffect — propojený seznam hooků na fiber uzlu. Nicméně, na rozdíl od useState, React nesleduje změny ref objektu, neřadí aktualizace do fronty a neplánuje opětovné vykreslení. To činí useRef extrémně lehkým hookem, který neovlivňuje výkon ani při častých změnách.

Podle React Team — Hooks FAQ (2025) je useRef v podstatě „krabička“, která ukládá hodnotu. Syntaktický cukr: const ref = useRef(initialValue) je ekvivalentní const ref = { current: initialValue } s tím rozdílem, že React zaručuje, že ref objekt bude při každém renderu stejný. Žádná magie — prostě stabilní reference spravovaná Reactem.

jsx
import { useRef } from 'react';

function Component() {
    const countRef = useRef(0);
    // countRef.current = 0 zpočátku
    // countRef.current = 5 po mutaci
    // Nedochází k opětovnému vykreslení!
}

Přístup k DOM elementům přes useRef

Nejčastější scénář použití useRef — získání přímého přístupu k DOM elementu. React přiřadí elementRef.current referenci na DOM uzel po připojení komponenty. To je nezbytné pro fokusování inputu, měření rozměrů elementu, integraci s animačními knihovnami a knihovnami, které nepoužívají React renderování.

React automaticky spravuje ref reference na DOM: při připojení přiřadí skutečný DOM uzel, při odpojení jej resetuje (nastaví null). To zaručuje, že v .current je vždy aktuální hodnota, a zabraňuje únikům paměti přes „visící“ reference na odstraněné elementy. Není vyžadováno ruční čištění.

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

    useEffect(() => {
        // Zaostřit input po připojení komponenty
        inputRef.current?.focus();
    }, []);

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

Podle React — Refs and DOM documentation (2025) nepoužívej ref pro deklarativní operace — otevírání/zavírání modálů, správu viditelnosti. Pro tyto účely existují state a props. Refs jsou určeny pro imperativní operace, které nelze vyjádřit deklarativně: fokus, výběr textu, integrace s knihovnami třetích stran.

Ukládání mutovatelných hodnot bez opětovného vykreslení

Druhý nejdůležitější scénář — ukládání libovolných hodnot, které musí být zachovány mezi rendery, ale jejich změna by neměla způsobit opětovné vykreslení. Typické příklady: identifikátory timerů (setInterval/setTimeout), příznaky pro zrušení požadavků, předchozí hodnoty props pro porovnání a jakákoli data, která neovlivňují výstup UI.

To je obzvláště užitečné v useEffect: useRef ukládá identifikátor timeru a cleanup jej čistí. Pokud je timerId uložen v useState, každé volání setTimerId by způsobilo zbytečné opětovné vykreslení, které není potřeba ani pro logiku, ani pro UI. useRef řeší tento problém bez režie a bez zbytečného překreslování.

jsx
function Timer() {
    const intervalRef = useRef(null);

    const start = () => {
        intervalRef.current = setInterval(() => {
            console.log('tik');
        }, 1000);
    };

    const stop = () => {
        clearInterval(intervalRef.current);
    };

    useEffect(() => stop, []);

    return <><button onClick={start}>Start</button><button onClick={stop}>Stop</button></>;
}

useRef vs useState: kdy co použít

Hlavní dilema — volba mezi useRef a useState — je vyřešeno jednou otázkou: „Je při změně hodnoty potřeba opětovné vykreslení?“. Pokud ano — useState. Pokud ne — useRef. useState ukládá stav, který ovlivňuje výstup komponenty; useRef ukládá data potřebná pro interní logiku, ale neovlivňující UI.

V praxi vývojáři často používají useRef k ukládání callbacků, aby se vyhnuli problémům s uzávěry. Například, pokud useEffect odebírá událost a uvnitř callbacku je potřeba aktuální state — ulož callback do useRef. Při každém renderu aktualizuj ref.current novou funkcí a efekt bude vždy volat čerstvý callback bez opětovného přihlášení.

KritériumuseRefuseState
Opětovné vykresleníNezpůsobuje při změněZpůsobuje při každém setState
MutacePřímá: ref.current = valuePřes setter: setState(value)
Použití v JSXNepoužívá se (žádný efekt)Používá se ve výstupu komponenty
PříkladTimery, DOM reference, předchozí hodnotyData formuláře, UI stav, příznaky

Existuje anti-vzor: použití useRef k ukládání dat potřebných v JSX, ale jejichž změna by neměla způsobit opětovné vykreslení. To vede k desynchronizaci — UI zobrazuje stará data, i když je ref.current již nový. Pokud je hodnota zobrazována v UI — použij useState. Pokud je používána pouze uvnitř logiky — useRef.

useRef v kombinaci s useEffect

Kombinace useRef + useEffect — standardní vzor pro sledování předchozích hodnot props. Ulož předchozí hodnotu do ref, porovnej s aktuální v useEffect a rozhodni se na základě rozdílu. To je obzvláště užitečné u animací, když potřebuješ vědět, jaká hodnota byla před změnou.

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>;
}

Podle React Documentation — Hooks FAQ (2025) se tento vzor nazývá „previous value pattern“. Funguje, protože useRef uchovává hodnotu mezi rendery a useEffect se spouští po potvrzení změn. Nejprve je DOM aktualizován novou price, poté useEffect porovná s předchozí (která je stále v ref) a aktualizuje ref.current na aktuální hodnotu.

Typické chyby s useRef

Nejčastější chyba — čtení ref.current ve fázi renderování pro výpočet JSX. Protože změna ref.current nezpůsobuje opětovné vykreslení, komponenta může používat zastaralou hodnotu. Pokud se hodnota .current účastní výstupu UI — použij useState. Pokud potřebuješ synchronizovat ref a state, použij useEffect k aktualizaci state z ref.

  • Ref v JSX — čtení ref.current uvnitř renderovací funkce vede k desynchronizaci UI a dat.
  • Ref jako závislost useEffect — ref.current by neměl být v poli závislostí; React nesleduje jeho změny.
  • Zapomenutá null kontrola — při odpojení se ref.current stane null; zkontroluj před přístupem.
  • Ukládání funkcí v ref — aktualizuj ref.current při každém renderu, pokud používáš vzor s čerstvým callbackem.
jsx
// ❌ Nečti ref.current během renderování pro zobrazení
function BadComponent() {
    const valRef = useRef(0);
    return <p>{valRef.current}</p>; // NEaktualizuje se při mutaci
}

// ✅ Použij state pro zobrazení, ref pro logiku
function GoodComponent() {
    const [val, setVal] = useState(0);
    const valRef = useRef(0);
    return <p>{val}</p>;
}

Další častá chyba — použití useRef jako jediného způsobu ukládání stavu v komponentě, když data přesto ovlivňují UI. Vývojáři volí useRef, aby se vyhnuli „zbytečnému“ opětovnému vykreslení, ale nakonec získají UI, které se neaktualizuje. Správný přístup: použij useState pro UI data a useRef pouze pro pomocné hodnoty, které se neúčastní renderování.

Často kladené otázky

Lze použít useRef k ukládání předchozího stavu?

Ano, toto je běžný vzor — previous state pattern. Vytvoř ref a aktualizuj ho v useEffect při každé změně sledované hodnoty. V okamžiku mezi renderem a efektem ref.current obsahuje předchozí hodnotu, kterou lze porovnat s aktuální. Nevyžaduje to další opětovná vykreslení a funguje s libovolnými datovými typy.

Proč je ref.current null při prvním renderu?

React přiřadí ref.current hodnotu DOM uzlu až poté, co je element vykreslen a přidán do skutečného DOM. Během prvního renderu komponenta ještě není připojena, proto je ref.current roven počáteční hodnotě (null). Přístup k DOM přes ref.current je možný pouze v useEffect nebo v obslužných rutinách událostí, které jsou volány po připojení.

Jaký je rozdíl mezi useRef a createRef?

createRef vytváří nový ref objekt při každém renderu — měl by být používán pouze v třídových komponentách. useRef vytváří ref jednou a vrací stejný objekt při všech následujících renderováních. Ve funkcionálních komponentách používej výhradně useRef; createRef povede ke ztrátě hodnoty při opětovném vykreslení, protože objekt bude znovu vytvořen.

Lze useRef předávat přes props?

Ano, ref objekt lze předat jako běžný prop: <Child inputRef={inputRef} />. Dceřiná komponenta jej používá přes inputRef.current. Nicméně pro přímé předání ref na DOM element dceřiné komponenty použij forwardRef — HOC, který umožňuje předání ref přes props. Bez forwardRef se ref automaticky nepřipojí k DOM elementu uvnitř dceřiné komponenty.

Jak změřit rozměr elementu pomocí useRef?

Připoj ref k elementu, poté v useEffect čti ref.current.getBoundingClientRect() nebo ref.current.offsetWidth / offsetHeight. Pro reaktivní sledování změn velikosti použij ResizeObserver uvnitř useEffect: vytvoř observer, přihlas se ke změnám a aktualizuj state novými rozměry. Nezapomeň observer vypnout v cleanup.

Shrnutí

  • useRef — hook pro vytvoření mutovatelného ref objektu, který je zachován mezi rendery bez vyvolání opětovného vykreslení.
  • Přístup k DOM — ref prop se předává elementu pro přímý přístup k DOM uzlu; dostupný po připojení.
  • Ukládání dat — timery, callbacky, příznaky a jakékoli hodnoty neovlivňující UI ukládej v ref.
  • useRef vs useState — vyber useState, pokud změna má překreslit UI; useRef — pokud ne.
  • Previous value pattern — ulož předchozí hodnotu do ref, aktualizuj v useEffect pro porovnání.
  • Ref v JSX — nečti ref.current ve fázi renderování; to vede k desynchronizaci UI a dat.
  • forwardRef — použij pro předání ref přes props do dceřiné komponenty.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také