Hodnoty, které se nevykreslují
Ref může držet jakoukoli hodnotu, nejen prvek. Představte si ho jako krabičku, kterou React komponentě schovává od jednoho vykreslení k dalšímu: dáte něco do ref.current a při dalším vykreslení to tam pořád je. A na rozdíl od stavu změna ref.current nové vykreslení nespustí.
To se hodí přesně pro věci, které potřebuje váš kód, ale stránka je neukazuje. Typický příklad je id intervalu, který jedno kliknutí spustí a jiné zastaví:
const intervalRef = useRef(null);
function spust() {
intervalRef.current = setInterval(() => {
setSekundy((sekundy) => sekundy + 1);
}, 1000);
}
function zastav() {
clearInterval(intervalRef.current);
}Proč ne něco jiného?
- Obyčejná proměnná
let idIntervalu;v komponentě vykreslení nepřežije. Při každém vykreslení React zavolá funkci komponenty znovu a ta začne s novou, prázdnou proměnnouidIntervalu. Za sekundu interval změní čas, komponenta se znovu vykreslí a id je pryč: Stop nemá co zastavit. - Stav by si id zapamatoval, ale každá změna stavu znamená nové vykreslení, a id přitom stránka vůbec neukazuje.
Takže: stav pro to, co ukazuje stránka, ref pro to, co potřebuje jen váš kód.
Ve stopkách se interval spouštěl v efektu, kdykoli se stopky rozběhly, a zastavoval ho úklid. Tady ho spouštějí a zastavují přímo obsluhy kliknutí, a tak musí jeho id mezi oběma kliknutími někde počkat.
Jak psát:
Pokyny
Vytvořte intervalRef pomocí useRef(null). Ve funkci spust spusťte interval, který každých 1000 milisekund zvětší sekundy o 1, a jeho id uložte do intervalRef.current.
Ve funkci zastav interval zastavte pomocí clearInterval(intervalRef.current).
Klikněte dvakrát na Start: běží dva intervaly, čas stoupá o 2 za sekundu a Stop zastaví jen ten druhý. Zařiďte, aby druhý Start nic neudělal: na začátku funkce spust ji ukončete pomocí return, když intervalRef.current není null. A ve funkci zastav nastavte intervalRef.current zpátky na null, aby Start po Stopu zase fungoval.