React 19: was ist neu und was ändert sich wirklich
AI generated
</>
{ }
React 19 · Server Components · Compiler · Migration
React 19: was ist neu
und was ändert sich wirklich

React 19 ist kein inkrementelles Update. Server Components verlassen die experimentelle Phase, Server Actions werden Teil des Kern-APIs, der React Compiler übernimmt automatisches Memoizing, und neue Hooks vereinfachen Formulare, optimistische Updates und Asset-Loading grundlegend. Was davon für bestehende Projekte relevant ist – und was sich tatsächlich im Alltag ändert.

20 Min. Lesezeit Server Components · Server Actions · useActionState · React Compiler · Asset Loading React 19 · Next.js · Remix · JavaScript

1. React 19 einordnen: Evolution oder Revolution?

React 19 ist das größte Release seit React 18 und den Concurrent Features – und es ist beides: Evolution in der API-Stabilisierung und Revolution im Programmiermodell. Was mit React 18 als experimentell eingeführt wurde, ist in React 19 stabil: Server Components, Streaming und der Concurrent Renderer. Was React 19 neu hinzufügt, ändert das Verhältnis zwischen Client und Server grundlegend. Statt alle Daten vom Client per fetch zu laden und asynchronen State mit useState zu verwalten, können Komponenten direkt auf dem Server rendern und auf Datenbanken, Dateisysteme und interne APIs zugreifen.

Das Missverständnis in der Community: React 19 ändert nicht, wie man einfache Client-Komponenten schreibt. useState, useEffect und die bekannten Patterns bleiben. Was sich ändert, ist das Gesamtbild: Wer Server Components und Server Actions einsetzt, schreibt deutlich weniger Boilerplate für Datenabruf, Ladezustand und Fehlerbehandlung. Wer den React Compiler aktiviert, kann auf viele manuelle useMemo- und useCallback-Aufrufe verzichten. Wer auf React 18 bleibt, verliert nichts – aber verpasst den größten Produktivitätsgewinn seit der Einführung von Hooks.

2. Server Components: was sie wirklich können und nicht können

Server Components in React 19 laufen auf dem Server und senden nur das gerenderte HTML und eine serialisierte Darstellung des Component-Trees zum Client – kein JavaScript-Bundle für die Komponente selbst. Das bedeutet: direkte Datenbankabfragen, Zugriff auf Dateisysteme, Verwendung privater API-Keys und Aufruf serverseitiger Services ohne eine eigene API-Route dazwischen. Das Ergebnis ist ein kleineres JavaScript-Bundle auf dem Client und deutlich einfacherer Code: kein useEffect für den Datenabruf, kein Loading-State für initiale Daten, keine Fehlerbehandlung für einen separaten API-Aufruf.

Was Server Components in React 19 nicht können: Hooks verwenden, Event-Handler haben, Browser-APIs aufrufen oder interaktiven State verwalten. Sie sind statisch in Bezug auf Interaktivität. Das führt zum hybriden Modell: Server Components für Datenabruf und initiales Rendering, Client Components (mit 'use client') für Interaktivität. Client Components können als Kinder von Server Components gerendert werden, erhalten ihre Props vom Server und verwalten danach ihren eigenen Zustand auf dem Client. Das Muster klingt komplex, ist aber in der Praxis klar: Alles, was keine Interaktion braucht, wird Server Component.


// Server Component — runs only on the server, no JS bundle sent to client
// Direct database access without an API route in between
import { db } from '@/lib/database';

async function ProductList({ categoryId }: { categoryId: string }) {
  // Direct DB query in a Server Component — no useEffect, no loading state
  const products = await db.query(
    'SELECT id, name, price FROM products WHERE category_id = $1',
    [categoryId]
  );

  return (
    <ul>
      {products.rows.map(product => (
        // Client Component can be a child of Server Component
        <li key={product.id}>
          <span>{product.name} — {product.price}€</span>
          <AddToCartButton productId={product.id} /> {/* Client Component */}
        </li>
      ))}
    </ul>
  );
}

// Client Component — interactive, has event handlers, uses hooks
'use client';
import { useState } from 'react';

function AddToCartButton({ productId }: { productId: string }) {
  const [added, setAdded] = useState(false);

  return (
    <button
      onClick={() => setAdded(true)}
      disabled={added}
    >
      {added ? 'Im Warenkorb' : 'In den Warenkorb'}
    </button>
  );
}

3. Server Actions: Formulare ohne API-Routen

Server Actions sind Funktionen, die in React 19 mit 'use server' markiert werden und auf dem Server ausgeführt werden, obwohl sie aus Client-Code aufgerufen werden. Das eliminiert einen der häufigsten Boilerplate-Bereiche in React-Anwendungen: eine Formular-Submission braucht keine separate API-Route, keinen fetch-Aufruf auf dem Client und keine manuelle Serialisierung der Formulardaten. Die Server Action empfängt direkt ein FormData-Objekt, führt die serverseitige Logik aus und gibt optional einen neuen State zurück.

Der entscheidende Vorteil von Server Actions in React 19 ist progressive Enhancement: Ein Formular mit einer Server Action als action-Attribut funktioniert auch ohne JavaScript – der Browser sendet das Formular als normalen POST-Request. Wenn JavaScript geladen ist, übernimmt React die Kontrolle und führt die Action ohne vollständigen Seiten-Reload aus. Das kombiniert die Einfachheit von klassischem HTML-Formular-Handling mit der Interaktivität moderner SPAs und macht das Ergebnis gleichzeitig accessibler und resilienter gegen JavaScript-Fehler.

4. Neue Hooks: useActionState, useFormStatus, useOptimistic

useActionState ist der zentrale neue React-19-Hook für die Arbeit mit Server Actions. Er nimmt eine Action-Funktion und einen initialen State entgegen und gibt den aktuellen State, eine wrapped Action und einen isPending-Boolean zurück. Der wrapped Action wird dem Formular als action-Attribut übergeben. Der State wird nach jeder Ausführung der Action aktualisiert und enthält sowohl Erfolgsdaten als auch Fehlermeldungen – je nachdem, was die Server Action zurückgibt. Das ersetzt vollständig das bisherige Muster aus useState für Lade- und Fehlerzustand und einem manuellen onSubmit-Handler.

useFormStatus liest den Pending-Zustand des übergeordneten Formulars aus einem Kindkomponent heraus. Das ermöglicht es, einen Submit-Button zu deaktivieren oder einen Ladeindikator anzuzeigen, ohne den Zustand explizit nach unten zu reichen. useOptimistic zeigt sofort einen optimistischen Wert an, bevor die Server Action abgeschlossen ist, und stellt den vorherigen Wert wieder her, falls die Action fehlschlägt. Gemeinsam bauen diese drei React-19-Hooks das vollständige Muster für interaktive, resiliente Formulare – mit weniger Code als jede bisherige Lösung.


'use server';
// Server Action — runs on the server, called from the client
import { revalidatePath } from 'next/cache';
import { db } from '@/lib/database';

type ActionState = { success: boolean; message: string } | null;

async function createProduct(prevState: ActionState, formData: FormData): Promise<ActionState> {
  const name = formData.get('name') as string;
  const price = parseFloat(formData.get('price') as string);

  if (!name || isNaN(price)) {
    return { success: false, message: 'Name und Preis sind erforderlich.' };
  }

  try {
    await db.query('INSERT INTO products (name, price) VALUES ($1, $2)', [name, price]);
    revalidatePath('/products');
    return { success: true, message: `Produkt "${name}" wurde erstellt.` };
  } catch {
    return { success: false, message: 'Datenbankfehler beim Erstellen des Produkts.' };
  }
}

// Client Component using the Server Action via useActionState
'use client';
import { useActionState } from 'react';

function CreateProductForm() {
  const [state, action, isPending] = useActionState(createProduct, null);

  return (
    <form action={action}>
      <input name="name" required placeholder="Produktname" />
      <input name="price" type="number" step="0.01" required placeholder="Preis" />
      <SubmitButton isPending={isPending} />
      {state && (
        <p style={ { color: state.success ? 'green' : 'red' } }>{state.message}</p>
      )}
    </form>
  );
}

// useFormStatus reads the pending state of the surrounding form
import { useFormStatus } from 'react-dom';

function SubmitButton({ isPending }: { isPending: boolean }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending || isPending}>
      {pending ? 'Wird gespeichert...' : 'Produkt erstellen'}
    </button>
  );
}

5. React Compiler: automatisches Memoizing ohne useMemo

Der React Compiler ist eine der am meisten diskutierten Neuerungen in React 19. Er analysiert React-Komponentencode zur Build-Zeit und fügt automatisch Memoizing-Aufrufe ein, wo sie semantisch sinnvoll sind. Das Ziel: Entwickler sollen sich nicht mehr darum kümmern müssen, ob ein Wert mit useMemo gecacht oder eine Funktion mit useCallback stabilisiert werden muss. Der Compiler erkennt, welche Werte sich zwischen Renders ändern können, und optimiert entsprechend.

Wichtig für das Verständnis von React 19: Der React Compiler ist ein Opt-in, kein zwingender Teil des Frameworks. Er erfordert validen, regelkonformen React-Code – also keine direkten Mutationen von State, keine Bedingungen vor Hook-Aufrufen, keine Side Effects in Renderung. Bestehende Codebases müssen möglicherweise refactored werden, bevor der Compiler vollständig aktiviert werden kann. Schrittweise Aktivierung per eslint-plugin-react-compiler ist der empfohlene Weg: Erst Lint-Fehler beheben, dann Compiler aktivieren. Der Nutzen ist erheblich: weniger manuelles Memoizing, bessere Performance by default, kürzere Codebases.

6. Asset Loading und Resource Preloading in React 19

React 19 bringt neue APIs für das Vorladen von Assets direkt aus React-Komponenten: preload(), prefetchDNS(), preconnect() und preinit() aus react-dom. Diese Funktionen generieren die entsprechenden Link-Tags im Dokument-Head, auch wenn sie tief in einem Komponentenbaum aufgerufen werden. Das ermöglicht es, Ressourcen genau dort anzufordern, wo sie in der Komponente benötigt werden – ohne das Head-Element manuell zu manipulieren oder eine Bibliothek wie react-helmet zu verwenden.

Für Stylesheet-Loading in React 19 gibt es eine elegante neue Möglichkeit: Stylesheets können direkt in Komponenten importiert und mit einer Precedence deklariert werden. React stellt sicher, dass die Stylesheets in der richtigen Reihenfolge und ohne Duplikate in den Head eingefügt werden. Das gilt auch für Server-rendered Stylesheets, die beim Streaming automatisch in den richtigen Teil des Dokuments eingefügt werden. Die Kombination aus Asset Preloading und Stylesheet-Management macht React 19 zu einem vollständigeren Framework für das Ressourcen-Management, ohne auf externe Bibliotheken angewiesen zu sein.

7. Breaking Changes und Deprecations in React 19

React 19 entfernt mehrere APIs, die seit React 18 als deprecated markiert waren. ReactDOM.render() und ReactDOM.hydrate() wurden durch ReactDOM.createRoot() und ReactDOM.hydrateRoot() ersetzt – wer noch die alten APIs verwendet, muss migrieren. Die Legacy Context API (contextTypes, childContextTypes, getChildContext) wird in React 19 vollständig entfernt; der Ersatz ist die moderne createContext-API. findDOMNode und String Refs gehören ebenfalls zu den entfernten APIs. Wer diese noch verwendet, muss vor dem Upgrade auf React 19 migrieren.

Auf der Seite der Verhaltensänderungen: In React 19 werden Fehler in der Fehlerbehandlung (Error Boundaries, onRecoverableError) nicht mehr doppelt geloggt. Das vereinfacht das Debugging. ref ist in React 19 ein normales Prop – forwardRef wird damit überflüssig und deprecated. Funktionskomponenten empfangen ref direkt als zweites Argument nicht mehr, sondern als Teil des props-Objekts. Das ist eine Breaking Change für alle Komponenten, die forwardRef verwenden – der Migrationspfad ist aber straightforward: forwardRef entfernen und ref direkt aus props lesen.


// React 18: forwardRef required to pass ref to function components
import { forwardRef } from 'react';

const Input = forwardRef<HTMLInputElement, { label: string }>(
  ({ label }, ref) => (
    <div>
      <label>{label}</label>
      <input ref={ref} />
    </div>
  )
);

// React 19: ref is a regular prop — no forwardRef needed
function Input({ label, ref }: { label: string; ref?: React.Ref<HTMLInputElement> }) {
  return (
    <div>
      <label>{label}</label>
      <input ref={ref} />
    </div>
  );
}

// React 18: ReactDOM.render (removed in React 19)
// ReactDOM.render(<App />, document.getElementById('root'));

// React 19: createRoot — already required since React 18, now the only option
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root')!);
root.render(<App />);

// React 19: ref cleanup function in useEffect style
function VideoPlayer({ src }: { src: string }) {
  return (
    <video
      src={src}
      ref={(node) => {
        if (node) {
          // Setup: ref attached
          node.play();
          // Cleanup function returned from ref callback
          return () => node.pause();
        }
      } }
    />
  );
}

8. Migration von React 18 auf React 19

Die Migration auf React 19 beginnt mit dem Codemod: npx react-codemod@latest cra-to-react-19 – aber dieses Tool deckt nicht alle Fälle ab und sollte nur als Startpunkt dienen. Der wichtigste manuelle Schritt: alle forwardRef-Verwendungen identifizieren und auf das neue ref-als-Prop-Modell migrieren. Danach die Legacy Context API, ReactDOM.render und findDOMNode ersetzen. TypeScript-Nutzer müssen auf @types/react@19 aktualisieren, da sich die Typdefinitionen für ref, children und viele Prop-Interfaces geändert haben.

Server Components und Server Actions sind kein Pflicht-Bestandteil von React 19 – sie erfordern Framework-Unterstützung (Next.js 15+, Remix, TanStack Start). Eine reine React-19-App ohne Framework kann Server Components nicht verwenden. Der React Compiler ist ebenfalls optional und erfordert eine separate Konfiguration. Der pragmatische Migrations-Ansatz: erst die Breaking Changes beheben, dann in einem nächsten Schritt die neuen Features evaluieren. Eine vollständige React-19-Migration in einer Woche durchzuführen ist unrealistisch für größere Codebases – ein schrittweiser Ansatz mit Feature-Flags und paralleler Entwicklung ist sicherer.

9. React 19 Features im direkten Vergleich zu React 18

Die größte Frage bei React 19 ist nicht "was ist neu", sondern "was ändert sich im Alltag". Dieser Vergleich zeigt die praktischen Unterschiede für typische Aufgaben.

Aufgabe React 18 React 19 Vorteil
Datenabruf useEffect + fetch + useState Server Component mit async/await Kein Loading-State, weniger Bundle
Formular Submit onSubmit + fetch + useState für Fehler Server Action + useActionState Kein API-Route, weniger Boilerplate
Memoizing Manuell useMemo / useCallback React Compiler automatisch Weniger Code, konsistentere Optimierung
ref weiterreichen forwardRef() wrapping ref als normales Prop Weniger Boilerplate, einfacherer Code
Optimist. Updates Manuell mit useState rollback-Logik useOptimistic Hook Automatisches Rollback bei Fehler
Asset Preloading react-helmet oder manuelle Manipulation preload(), preinit() aus react-dom Kein externe Bibliothek nötig

Die Tabelle zeigt: React 19 vereinfacht primär die Bereiche, die in React 18 noch viel Boilerplate erforderten. Datenabruf, Formular-Handling und Memoizing sind die drei größten Produktivitätsprobleme in React-18-Codebases – und alle drei werden in React 19 grundlegend vereinfacht. Wer diese Features nutzen will, braucht Framework-Unterstützung für Server Components und Server Actions.

Mironsoft

React-Migration, Server Components und moderne Frontend-Architektur

React-19-Migration für euer Projekt?

Wir analysieren bestehende React-18-Codebases auf Migrationspfade zu React 19, identifizieren Breaking Changes und begleiten die schrittweise Einführung von Server Components, Server Actions und dem React Compiler.

Migrations-Audit

Codebase-Analyse auf Breaking Changes, forwardRef, Legacy Context und deprecated APIs

Server Components

Architektur-Planung für Server Components und Server Actions in Next.js 15 oder Remix

React Compiler

Schrittweise Aktivierung des React Compilers mit ESLint-Plugin und Codebase-Bereinigung

10. Zusammenfassung

React 19 ist ein Release, das das Komponentenmodell um eine Server-Dimension erweitert und gleichzeitig bestehende Schmerzpunkte durch neue Hooks und den React Compiler adressiert. Server Components ermöglichen direkten Datenbankzugriff ohne API-Routen. Server Actions vereinfachen Formular-Handling auf ein Niveau, das früher komplexe Bibliotheken erforderte. useActionState, useFormStatus und useOptimistic sind die passenden Client-seitigen Hooks dazu. Der React Compiler übernimmt automatisches Memoizing und reduziert manuellen Optimierungs-Overhead erheblich.

Die Breaking Changes in React 19 sind real, aber bewältigbar: forwardRef durch das neue ref-als-Prop-Modell ersetzen, Legacy Context APIs migrieren, ReactDOM.render durch createRoot ersetzen. Wer TypeScript verwendet, muss die aktualisierten Typen berücksichtigen. Der Migrations-Aufwand zahlt sich aus: React 19 ist die Grundlage für die nächsten Jahre der React-Ökosystem-Entwicklung, und alle wichtigen Frameworks und Bibliotheken orientieren sich an seinen neuen Primitiven.

React 19 — Das Wichtigste auf einen Blick

Server-Features

Server Components für direkten Datenabruf ohne API-Routen. Server Actions für Formular-Handling ohne onSubmit + fetch. Framework-Unterstützung (Next.js 15+) erforderlich.

Neue Hooks

useActionState verbindet Actions mit State. useFormStatus liest Pending-Zustand aus Kindkomponenten. useOptimistic für automatisches Rollback bei Fehlern.

Breaking Changes

forwardRef deprecated, ref ist normales Prop. ReactDOM.render entfernt. Legacy Context API entfernt. TypeScript-Typen geändert – @types/react@19 aktualisieren.

React Compiler

Optionales Opt-in für automatisches Memoizing. Erfordert regelkonformen React-Code. Schrittweise Aktivierung mit eslint-plugin-react-compiler empfohlen.

11. FAQ: React 19 – was ist neu und was ändert sich wirklich

1Muss ich sofort auf Server Components umsteigen?
Nein. React 19 ist abwärtskompatibel. Server Components sind optional und erfordern Framework-Unterstützung. Alle Komponenten können weiterhin als Client Components geschrieben werden.
2Wichtigste Breaking Changes in React 19?
forwardRef deprecated. ReactDOM.render() entfernt. Legacy Context API entfernt. findDOMNode entfernt. TypeScript-Typen geändert – @types/react@19 aktualisieren.
3React 18 Komponenten in React 19?
Ja, mit Ausnahmen. forwardRef, ReactDOM.render, Legacy Context und findDOMNode müssen migriert werden. Der Rest funktioniert ohne Änderungen.
4useActionState vs. altes Formular-Pattern?
useActionState ersetzt useState für Lade-/Fehlerzustand, onSubmit-Handler und fetch-Aufruf durch einen einzigen Hook mit State, Action und isPending.
5Next.js für Server Components erforderlich?
Ja. Server Components erfordern Framework-Unterstützung. Next.js 15+, Remix und TanStack Start unterstützen sie. Pure React ohne Framework kann sie nicht nutzen.
6Ist der React Compiler produktionsreif?
Ja, als Opt-in. Erfordert regelkonformen Code ohne State-Mutationen. Schrittweise Aktivierung mit eslint-plugin-react-compiler empfohlen.
7TypeScript-Änderungen in React 19?
ref, children und viele Prop-Interfaces geändert. @types/react@19 aktualisieren und TypeScript-Fehler systematisch beheben. Codemod hilft bei forwardRef-Migration.
8React 18 noch lange supported?
Kein fester EOL kommuniziert. Neue Projekte sollten React 19 verwenden. Bestehende Projekte können schrittweise migrieren.
9Was ist useOptimistic?
Zeigt sofort optimistischen Wert an, bevor Server Action abgeschlossen ist. Automatisches Rollback bei Fehler. Typisch für Like-Buttons und sofortiges User-Feedback.
10Server Actions ohne Server Components?
Ja. Server Actions können direkt aus Client Components aufgerufen werden. Formular-action-Prop reicht – keine separate API-Route, keine Server Component nötig.