Hirefullstack – Software Engineering & IT-Beratung aus Berlin
← Zur Übersicht
Einstieg 7 Min Lesezeit

useId & useDebugValue

Stabile IDs für Formulare – und ein Label für die DevTools

In einem Satz

useId erzeugt eine eindeutige ID, die auf Server und Client identisch ist. Gedacht für die Verbindung von Label und Eingabefeld – nicht für Listen-Keys.

In HTML gehören Beschriftung und Eingabefeld über eine ID zusammen: <label htmlFor="mail"> zeigt auf <input id="mail">. Nur klickt man dann bei zwei solchen Feldern auf der Seite immer ins erste – die ID kommt ja doppelt vor.

Eine Zufallszahl wäre die naheliegende Lösung, geht aber beim Server-Rendering (SSR)Die Seite wird schon auf dem Server als fertiges HTML erzeugt, damit der Browser sofort etwas anzeigen kann. schief: Server und Browser würfeln verschieden, und React beschwert sich über einen HydrationDer Moment, in dem React das vom Server gelieferte HTML im Browser „übernimmt“ und zum Leben erweckt.Passt das HTML nicht zu dem, was React im Browser erzeugen würde, gibt es einen Hydration-Fehler.-Fehler. useId löst beides.

feld.tsx
function Feld({ label }: { label: string }) {
  const id = useId();

  return (
    <>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </>
  );
}

// Mehrere IDs aus einem Aufruf ableiten – so ist es gedacht:
function Anmeldung() {
  const id = useId();
  return (
    <>
      <label htmlFor={id + "-mail"}>E-Mail</label>
      <input id={id + "-mail"} />

      <label htmlFor={id + "-pw"}>Passwort</label>
      <input id={id + "-pw"} aria-describedby={id + "-hinweis"} />
      <p id={id + "-hinweis"}>Mindestens 12 Zeichen</p>
    </>
  );
}
Nimm es, wenn …
  • +

    htmlFor / id zwischen Label und Feld

  • +

    aria-describedby, aria-labelledby, aria-controls

  • +

    Wiederverwendbare Komponenten, die mehrfach auf einer Seite stehen können

Lass es, wenn …
  • Als key in Listen – dafür brauchst du eine ID aus den Daten

  • Als ID für Datensätze in einer Datenbank

  • Als Ersatz für crypto.randomUUID()

Stolperstein Kein Schlüssel für Listen

useId gibt pro Komponenteninstanz einen stabilen Wert – in einer Schleife bekämst du für jedes Element denselben. Keys müssen aus den Daten kommen.

Genauer erklärt: useDebugValue optional

Der zweite Hook in dieser Lektion ist schnell erzählt: useDebugValue schreibt in den React DevTools ein kleines Etikett neben deinen eigenen Hook – etwa useOnline: "online". Auf das Verhalten deiner App hat er null Einfluss.

debug.ts
function useOnline() {
  const [online, setOnline] = useState(true);
  useDebugValue(online ? "online" : "offline");
  return online;
}

Nützlich, wenn du eine Hook-Bibliothek schreibst. In normalem Anwendungscode brauchst du ihn nicht.

Sitzt das schon?

2 Fragen zu dieser Lektion. Falsche Antworten landen in deiner Statistik.

Jetzt selbst schreiben

Zugängliches Feld bauen

Die Komponente Feld wird zweimal gerendert. Aktuell teilen sich beide Instanzen dieselbe ID – ein Klick auf das zweite Label fokussiert das erste Feld. Repariere das mit useId.

  • Jedes <input> hat eine eigene, eindeutige ID
  • htmlFor des Labels zeigt jeweils auf das zugehörige Feld
  • Ein Klick auf ein Label fokussiert genau dessen Eingabefeld
import { useId } from "react";

function Feld({ label }: { label: string }) {
  // TODO: eindeutige ID erzeugen
  return (
    <p>
      <label htmlFor="feld">{label}</label>{" "}
      <input id="feld" />
    </p>
  );
}

export default function App() {
  return (
    <div style={{ fontFamily: "system-ui", padding: 16 }}>
      <Feld label="Vorname" />
      <Feld label="Nachname" />
    </div>
  );
}

Hirefullstack

Ihr braucht React-Verstärkung im Team?

Wir bauen seit Jahren React- und Next.js-Anwendungen für Kunden in ganz Deutschland – als einzelner Experte, als Verstärkung fürs Bestandsteam oder als komplettes Scrum-Team.

Projekt besprechen →