useRef verstehen: DOM-Zugriff in React
useRef verstehen
~10 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
useRef hat zwei sehr unterschiedliche, aber gleich wichtige Anwendungsfälle: direkten Zugriff auf ein echtes DOM-Element bekommen, und einen Wert über mehrere Render-Durchläufe hinweg "merken", OHNE dass sich dadurch ein Neuzeichnen auslöst (anders als bei useState).
Anwendungsfall 1: direkter Zugriff auf ein DOM-Element
Normalerweise beschreiben Sie in React nur, WIE die Oberfläche aussehen soll, und rühren das eigentliche DOM nie manuell an. Manchmal brauchen Sie aber doch direkten Zugriff – zum Beispiel, um ein Eingabefeld automatisch zu fokussieren, sobald die Seite geladen ist. Dafür ist useRef da:
import { useRef, useEffect } from 'react';
function Suchfeld() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // echtes DOM-Element, direkt ansprechbar
}, []);
return <input ref={inputRef} type="text" />;
}useRef(null) erzeugt ein Objekt mit genau einer Eigenschaft: current, anfangs null. Wird dasselbe Objekt als ref-Prop an ein JSX-Element übergeben, füllt React inputRef.current automatisch mit dem echten DOM-Knoten, sobald er existiert – ab da können Sie normale DOM-Methoden wie .focus(), .scrollIntoView() oder .value darauf aufrufen.
App.jsx erweitern: ein automatisch fokussiertes Suchfeld
Bauen wir das direkt in unser Projekt ein – ein Suchfeld, das die Produktliste filtert UND beim Laden automatisch den Fokus bekommt. Ersetzen Sie src/App.jsx:
import { useEffect, useRef, useState } from 'react';
import ProductCard from './components/ProductCard';
const SAMPLE_PRODUCTS = [
{ sku: 'schuhe-01', name: 'Wanderschuhe', price: 89.99, imageUrl: 'https://picsum.photos/seed/1/300' },
{ sku: 'rucksack-01', name: 'Trekking-Rucksack', price: 59.5, imageUrl: 'https://picsum.photos/seed/2/300' },
{ sku: 'jacke-01', name: 'Regenjacke', price: 74.0, imageUrl: 'https://picsum.photos/seed/3/300' },
];
function App() {
const [query, setQuery] = useState('');
const searchInputRef = useRef(null);
useEffect(() => {
document.title = `Produktkatalog (${SAMPLE_PRODUCTS.length} Produkte)`;
searchInputRef.current.focus();
}, []);
const gefiltert = SAMPLE_PRODUCTS.filter((produkt) =>
produkt.name.toLowerCase().includes(query.toLowerCase())
);
return (
<div className="app">
<h1>Produktkatalog</h1>
<input
ref={searchInputRef}
type="text"
placeholder="Produkt suchen..."
value={query}
onChange={(event) => setQuery(event.target.value)}
/>
<div className="product-grid">
{gefiltert.map((produkt) => (
<ProductCard
key={produkt.sku}
name={produkt.name}
price={produkt.price}
imageUrl={produkt.imageUrl}
onSelect={() => alert(produkt.name + ' angeklickt')}
/>
))}
</div>
</div>
);
}
export default App;value={{query}} + onChange={{(event) => setQuery(event.target.value)}} ist ein sogenanntes "kontrolliertes" Eingabefeld – der WERT kommt aus React-State (useState), während ref zusätzlich Zugriff auf das ECHTE DOM-Element gibt, um .focus() aufzurufen. Beide Konzepte schließen sich nicht aus, sie lösen unterschiedliche Probleme – mehr zu kontrollierten Feldern in Kapitel 13.
Anwendungsfall 2: Werte merken, ohne neu zu rendern
Der zweite, weniger offensichtliche Anwendungsfall: useRef kann auch als "Container" für einen beliebigen veränderlichen Wert dienen, der über Render-Durchläufe hinweg erhalten bleibt – im Gegensatz zu useState löst das Ändern von ref.current aber KEIN Neuzeichnen aus:
function KlickZaehler() {
const anzahlKlicksRef = useRef(0);
function handleClick() {
anzahlKlicksRef.current = anzahlKlicksRef.current + 1;
console.log('Bisher geklickt:', anzahlKlicksRef.current);
// Kein Re-Render! Die Anzeige würde sich NICHT aktualisieren,
// selbst wenn wir {anzahlKlicksRef.current} im JSX anzeigen würden.
}
return <button onClick={handleClick}>Klick mich</button>;
}Achtung: Genau DESHALB ist useRef die falsche Wahl, wenn ein geänderter Wert auch tatsächlich auf dem Bildschirm sichtbar werden soll – dafür ist useState da. Nutzen Sie useRef für Werte, die "im Hintergrund" mitlaufen sollen (Timer-IDs, Vorher-Werte zum Vergleich, DOM-Elemente), aber nie direkt im JSX angezeigt werden.