useRef — är en React-hook som skapar ett muterbart ref-objekt med egenskapen .current, som bevaras mellan komponentens renderingar. Till skillnad från useState orsakar inte ändring av .current en omrendering, vilket gör useRef idealiskt för att lagra DOM-referenser, timerar och alla värden som måste överleva renderingar utan att rita om UI. Enligt React Documentation (2025) skapas ref-objektet en gång under komponentens livstid och ändras inte mellan renderingar, vilket garanterar referensens stabilitet.
Huvudpunkter
useRef — är en hook som lades till i React 16.8 och returnerar ett muterbart ref-objekt med en enda egenskap .current. Det initiala värdet tilldelas .current vid montering av komponenten. Huvudskillnaden från en vanlig variabel — ref-objektet överlever omrenderingar: vid omrendering skapar React inte om ref, utan returnerar samma objekt.
Den interna implementeringen av useRef använder samma mekanism som useState och useEffect — en länkad lista av hooks på fiber-noden. Men till skillnad från useState övervakar React inte ändringar av ref-objektet, köar inte uppdateringar och planerar inte omrendering. Detta gör useRef till en extremt lätt hook som inte påverkar prestandan även vid frekventa ändringar.
Enligt React Team — Hooks FAQ (2025) är useRef i grunden en ”låda” som lagrar ett värde. Syntaktiskt socker: const ref = useRef(initialValue) är ekvivalent med const ref = { current: initialValue } med skillnaden att React garanterar att ref-objektet kommer att vara detsamma vid varje rendering. Ingen magi — bara en stabil referens som hanteras av React.
import { useRef } from 'react';
function Component() {
const countRef = useRef(0);
// countRef.current = 0 initialt
// countRef.current = 5 efter mutation
// Ingen omrendering sker!
}
Det vanligaste användningsscenariot för useRef — att få direkt åtkomst till DOM-elementet. React tilldelar elementRef.current referensen till DOM-noden efter montering av komponenten. Detta är nödvändigt för att fokusera input, mäta dimensioner på element, integrera med animationsbibliotek och bibliotek som inte använder React-rendering.
React hanterar automatiskt ref-referenser till DOM: vid montering tilldelas den faktiska DOM-noden, vid avmontering återställs den (sätts till null). Detta garanterar att .current alltid har ett aktuellt värde och förhindrar minnesläckor via ”hängande” referenser till borttagna element. Ingen manuell rengöring krävs.
function AutoFocusInput() {
const inputRef = useRef(null);
useEffect(() => {
// Fokusera input efter montering av komponent
inputRef.current?.focus();
}, []);
return <input ref={inputRef} type="text" />;
}
Enligt React — Refs and DOM documentation (2025), använd inte ref för deklarativa operationer — öppna/stänga modaler, hantera synlighet. För dessa ändamål finns state och props. Ref är avsedda för imperativa operationer som inte kan uttryckas deklarativt: fokus, textmarkering, integration med tredjepartsbibliotek.
Det näst viktigaste scenariot — lagring av godtyckliga värden som måste bevaras mellan renderingar, men vars ändring inte bör orsaka omrendering. Typiska exempel: timer-identifierare (setInterval/setTimeout), flaggor för att avbryta förfrågningar, tidigare prop-värden för jämförelse och alla data som inte påverkar UI-utdata.
Detta är särskilt användbart i useEffect: useRef lagrar timer-identifieraren och rensningen tar bort den. Om timerId lagras i useState skulle varje anrop till setTimerId orsaka en onödig omrendering som varken behövs för logiken eller UI. useRef löser detta problem utan overhead och utan onödig omritning.
function Timer() {
const intervalRef = useRef(null);
const start = () => {
intervalRef.current = setInterval(() => {
console.log('tick');
}, 1000);
};
const stop = () => {
clearInterval(intervalRef.current);
};
useEffect(() => stop, []);
return <><button onClick={start}>Start</button><button onClick={stop}>Stop</button></>;
}
Huvuddilemmat — valet mellan useRef och useState — löses med en fråga: ”Behövs omrendering vid ändring av värdet?”. Om ja — useState. Om nej — useRef. useState lagrar tillstånd som påverkar komponentens utdata; useRef lagrar data som behövs för intern logik men som inte påverkar UI.
I praktiken använder utvecklare ofta useRef för att lagra callbacks, för att undvika problem med closures. Till exempel, om useEffect prenumererar på en händelse och inuti callbacken behövs aktuellt state — lagra callbacken i useRef. Vid varje rendering uppdatera ref.current med den nya funktionen och effekten kommer alltid att anropa den färska callbacken utan att prenumerera om.
| Kriterium | useRef | useState |
|---|---|---|
| Omrendering | Orsakar inte vid ändring | Orsakar vid varje setState |
| Mutation | Direkt: ref.current = value | Via setter: setState(value) |
| Användning i JSX | Används inte (ingen effekt) | Används i komponentens utdata |
| Exempel | Timerar, DOM-referenser, tidigare värden | Formulärdata, UI-tillstånd, flaggor |
Det finns ett anti-mönster: att använda useRef för att lagra data som behövs i JSX, men vars ändring inte bör orsaka omrendering. Detta leder till desynkronisering — UI visar gamla data, medan ref.current redan är nytt. Om värdet visas i UI — använd useState. Om det bara används inom logiken — useRef.
Kombinationen useRef + useEffect — ett standardmönster för att spåra tidigare prop-värden. Lagra det tidigare värdet i ref, jämför med det aktuella i useEffect och fatta ett beslut baserat på skillnaden. Detta är särskilt användbart vid animationer, när du behöver veta vilket värde som fanns före ändringen.
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>;
}
Enligt React Documentation — Hooks FAQ (2025) kallas detta mönster ”previous value pattern”. Det fungerar eftersom useRef behåller värdet mellan renderingar och useEffect körs efter att ändringarna har bekräftats. Först uppdateras DOM med det nya price, sedan jämför useEffect med det tidigare (som fortfarande finns i ref) och uppdaterar ref.current till det aktuella värdet.
Det vanligaste misstaget — att läsa ref.current i renderingsfasen för att beräkna JSX. Eftersom ändring av ref.current inte orsakar omrendering kan komponenten använda ett föråldrat värde. Om värdet på .current deltar i UI-utdata — använd useState. Om du behöver synkronisera ref och state, använd useEffect för att uppdatera state från ref.
// ❌ Läs inte ref.current under rendering för visning
function BadComponent() {
const valRef = useRef(0);
return <p>{valRef.current}</p>; // kommer INTE att uppdateras vid mutation
}
// ✅ Använd state för visning, ref för logik
function GoodComponent() {
const [val, setVal] = useState(0);
const valRef = useRef(0);
return <p>{val}</p>;
}
Ett annat vanligt misstag — att använda useRef som det enda sättet att lagra tillstånd i komponenten, när data ändå påverkar UI. Utvecklare väljer useRef för att undvika ”onödig” omrendering, men får till slut ett UI som inte uppdateras. Rätt tillvägagångssätt: använd useState för UI-data och useRef endast för hjälpvärden som inte deltar i renderingen.
Vanliga frågor
Ja, detta är ett vanligt mönster — previous state pattern. Skapa en ref och uppdatera den i useEffect vid varje ändring av det spårade värdet. I ögonblicket mellan rendering och effekt innehåller ref.current det tidigare värdet som kan jämföras med det aktuella. Detta kräver inga ytterligare omrenderingar och fungerar med alla datatyper.
React tilldelar ref.current värdet av DOM-noden först efter att elementet har renderats och lagts till i den verkliga DOM. Under den första renderingen är komponenten ännu inte monterad, därför är ref.current lika med det initiala värdet (null). Åtkomst till DOM via ref.current är endast möjlig i useEffect eller i händelsehanterare som anropas efter montering.
createRef skapar ett nytt ref-objekt vid varje rendering — bör endast användas i klasskomponenter. useRef skapar ref en gång och returnerar samma objekt vid alla efterföljande renderingar. I funktionella komponenter använd endast useRef; createRef leder till förlust av värdet vid omrendering, eftersom objektet kommer att återskapas.
Ja, ref-objektet kan skickas som en vanlig prop: <Child inputRef={inputRef} />. Barnelementet använder det via inputRef.current. För att direkt skicka ref till DOM-elementet i barnelementet, använd forwardRef — en HOC som gör att ref kan skickas via props. Utan forwardRef kommer ref inte automatiskt att kopplas till DOM-elementet inuti barnelementet.
Koppla ref till elementet, läs sedan i useEffect ref.current.getBoundingClientRect() eller ref.current.offsetWidth / offsetHeight. För reaktiv spårning av storleksändringar, använd ResizeObserver inuti useEffect: skapa en observer, prenumerera på ändringar och uppdatera state med nya dimensioner. Glöm inte att inaktivera observern i rensningen.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också