React 19 to główna wersja Reacta wydana w grudniu 2024. Dodaje akcje (Actions, funkcje async zarządzające stanem oczekiwania, błędami i formularzami), hooki useActionState, useOptimistic i use, ref jako zwykły prop oraz tagi <title> i <meta>, które React przenosi do head dokumentu. React 19.2 (październik 2025) dodał <Activity> i useEffectEvent.
Każdy przykład poniżej działa na React 19.2. Oto akcja: funkcja async przekazana do formularza, ze stanem oczekiwania i zwróconym błędem obsłużonymi przez useActionState.
Naciśnij Save przy pustym polu, żeby zobaczyć błąd, a potem wpisz imię i zapisz: przycisk przez 800 ms pokazuje "Saving...". Nie ma tu useState dla błędu, flagi isLoading ani e.preventDefault().
Akcje i akcje formularzy
W React 18 dla każdego formularza pisałeś te same kroki: zablokuj domyślne wysłanie, ustaw flagę ładowania, poczekaj na żądanie, zapisz błąd, wyczyść flagę. React 19 nazywa funkcję, która wykonuje pracę asynchroniczną wewnątrz przejścia, akcją (Action) i sam prowadzi tę buchalterię.
startTransition(iuseTransition) przyjmują teraz funkcję async.isPendingpozostajetrue, dopóki cała funkcja się nie skończy.<form action={fn}>wywołujefnzFormDataformularza, gdy formularz jest wysyłany. Działa jako akcja, a po jej zakończeniu React resetuje niekontrolowane pola formularza.<button formAction={fn}>daje jednemu przyciskowi wysyłania własną akcję.- useActionState zachowuje wartość, którą akcja zwróciła ostatnio, więc akcja może zwrócić komunikat o błędzie albo zapisany rekord.
useFormStatuszreact-dompozwala komponentowi wewnątrz formularza odczytać, czy ten formularz jest wysyłany, bez przekazywania propsów w dół. Potrzebuje rodzica<form>, więc tutaj pojawia się w statycznym bloku:
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>{pending ? 'Sending...' : 'Send'}</button>;
}
useOptimistic
useOptimistic pokazuje wynik, którego się spodziewasz, dopóki akcja jeszcze trwa, i wraca do prawdziwego stanu, gdy akcja się kończy. Licznik polubień może wzrosnąć w chwili kliknięcia i spaść z powrotem, jeśli żądanie się nie powiedzie.
const [optimisticLikes, addOptimisticLike] = useOptimistic(likes, (current, delta) => current + delta);
Strona o useOptimistic ma działający przykład z udawanym API, które celowo zawodzi, żebyś mógł obejrzeć wycofanie zmiany.
API use
use odczytuje wartość z obietnicy albo z kontekstu. Z obietnicą zawiesza komponent, dopóki obietnica się nie rozwiąże, a najbliższe <Suspense> pokazuje w tym czasie swój widok zastępczy. W odróżnieniu od każdego innego hooka use można wywołać wewnątrz if albo pętli i po wczesnym return.
React 19 pozwala też renderować bezpośrednio <ThemeContext value="dark"> zamiast <ThemeContext.Provider>. Oba pojawiają się w tym przykładzie:
ref jako prop i czyszczenie refów
Komponent funkcyjny dostaje teraz ref jak każdy inny prop. Nie musisz już owijać go w forwardRef, żeby przekazać ref do elementu DOM.
Ref callback może też zwrócić funkcję czyszczącą. React wywołuje ją, gdy element znika z ekranu, tak samo jak działa funkcja czyszcząca efektu. Callback, który nic nie zwraca, nadal jest wywoływany z null przy usunięciu, jak w React 18.
Kliknij kilka razy przycisk i przeczytaj konsolę: każde usunięcie wypisuje linię czyszczenia, każdy powrót wypisuje attached to DIV.
Metadane dokumentu
Możesz renderować <title>, <meta> i <link> w dowolnym miejscu komponentu, a React przeniesie je do <head>. Komponent strony może ustawić własny tytuł bez biblioteki takiej jak react-helmet.
Podgląd nie ma karty przeglądarki, którą mógłby pokazać, więc efekt zamiast tego wypisuje document.title. Zmieniaj artykuły, a wypisywany tytuł za nimi podąży.
Arkusze stylów potraktowano tak samo: <link rel="stylesheet" href="..." precedence="default" /> wewnątrz komponentu jest wstawiany do head raz, według kolejności pierwszeństwa, a React czeka na niego, zanim pokaże treść, która go potrzebuje. <script async src="..."> renderowany przez kilka komponentów ładuje się tylko raz. react-dom eksportuje też preload, preinit, preconnect i prefetchDNS do wskazówek o zasobach.
Activity i useEffectEvent (React 19.2)
<Activity mode="hidden"> ukrywa swoje dzieci bez wyrzucania ich stanu. React ukrywa DOM, uruchamia funkcje czyszczące efektów i przywraca wszystko, gdy tryb znów zmieni się na "visible". Pasuje do kart i paneli, do których spodziewasz się, że użytkownik wróci.
Wpisz notatkę, przełącz na About i z powrotem. Tekst nadal tam jest, a konsola pokazuje, że efekt został wyczyszczony na czas ukrycia. Zastąp opakowanie <Activity> przez {tab === 'notes' && <Notes />}, a notatka będzie ginąć przy każdym przełączeniu.
useEffectEvent wyjmuje funkcję z zależności efektu. Funkcja zawsze widzi najnowsze propsy i stan, ale ich zmiana nie uruchamia efektu od nowa:
function ChatRoom({ roomId, theme }) {
const onConnected = useEffectEvent(() => {
showNotification('Connected!', theme);
});
useEffect(() => {
const connection = createConnection(roomId);
connection.on('connected', () => onConnected());
connection.connect();
return () => connection.disconnect();
}, [roomId]); // theme is not a dependency
}
19.2 dodał też cacheSignal dla komponentów serwerowych (mówi, kiedy wynik cache() nie jest już potrzebny) i ścieżki wydajności (Performance Tracks) w panelu wydajności Chrome DevTools. React 19.1 dodał captureOwnerStack, funkcję dostępną tylko w trybie deweloperskim, która zwraca, które komponenty wyrenderowały bieżący.
Komponenty serwerowe i funkcje serwerowe
Komponenty serwerowe (Server Components) to komponenty, które wykonują się z wyprzedzeniem na serwerze (albo w czasie budowania) i wysyłają swój wynik do przeglądarki. Mogą być async i bezpośrednio czytać bazę danych, a ich kod nigdy nie trafia do klienta. Funkcje serwerowe (Server Functions, wcześniej nazywane Server Actions) to funkcje async oznaczone 'use server', które komponent kliencki może wywołać jak zwykłą funkcję. Oba wymagają frameworka z bundlerem, który je obsługuje, takiego jak App Router w Next.js, więc nie da się ich uruchomić w tym edytorze.
// A Server Component: async, runs on the server only
export default async function Notes() {
const notes = await db.notes.findMany();
return notes.map((note) => <Note key={note.id} note={note} />);
}
// A Server Function, usable as a form action
async function createNote(formData) {
'use server';
await db.notes.create({ text: formData.get('text') });
}
Usunięte i zmienione API
React 19 usunął API, które od lat były oznaczone jako przestarzałe:
| Usunięte | Czego używać zamiast |
|---|---|
ReactDOM.render, ReactDOM.hydrate | createRoot, hydrateRoot z react-dom/client |
unmountComponentAtNode | root.unmount() |
findDOMNode | ref na elemencie DOM |
String refs (ref="input") | useRef albo ref callback |
Przestarzały kontekst (contextTypes, getChildContext) | createContext ze static contextType albo use |
Sprawdzanie propTypes (teraz po cichu ignorowane) | TypeScript albo własne sprawdzenia |
defaultProps w komponentach funkcyjnych | domyślne wartości parametrów |
react-dom/test-utils | act z react; do reszty React Testing Library |
react-test-renderer/shallow | pakiet react-shallow-renderer |
React.createFactory | JSX |
Komponenty klasowe zachowują defaultProps. Inaczej zgłaszane są też błędy: błędy złapane przez granicę błędów są wypisywane raz przez console.error, niezłapane trafiają do window.reportError, a createRoot przyjmuje opcje onCaughtError i onUncaughtError, żebyś mógł je zgłaszać sam.
Aktualizacja do React 19
Najpierw zaktualizuj do React 18.3. Jest identyczny z 18.2, ale ostrzega przed przestarzałymi API i innymi zmianami, których wymaga React 19, więc możesz je poprawić, dopóki aplikacja jeszcze działa. React 19 wymaga też nowoczesnej transformacji JSX, której Vite i każdy obecny framework już używają. Potem zainstaluj React 19:
npm install react@^19 react-dom@^19
npm install --save-dev @types/react@^19 @types/react-dom@^19
Oficjalny przewodnik aktualizacji wskazuje codemody do mechanicznych zmian. Pierwszy obejmuje string refs, importy act i ReactDOM.render; drugi aktualizuje kod TypeScript pod nowe typy:
npx codemod@latest react/19/migration-recipe
npx types-react-codemod@latest preset-19 ./src
Po aktualizacji nic nie zmusza cię do przejścia na akcje ani nowe hooki. Istniejące komponenty, hooki i komponenty klasowe dalej działają; formularze możesz przenosić na <form action> po jednym.
Najczęściej zadawane pytania
Kiedy wydano React 19?
React 19 stał się stabilny w grudniu 2024. React 19.1 pojawił się w marcu 2025, a React 19.2 w październiku 2025.
Jakie są największe zmiany w React 19?
Akcje (funkcje async, które same obsługują stan oczekiwania, błędy i formularze), hooki useActionState, useOptimistic i use, ref jako zwykły prop, <Context> jako provider oraz tagi <title> i <meta>, które przenoszą się do head dokumentu. Komponenty serwerowe stały się stabilne dla frameworków.
Czy forwardRef jest przestarzałe w React 19?
Komponenty funkcyjne mogą teraz przyjmować ref jako zwykły prop, więc nowy kod nie potrzebuje forwardRef. Nadal działa, a zespół Reacta zapowiedział, że w przyszłej wersji zostanie oznaczony jako przestarzały.
Czy React 19 zepsuje moją aplikację w React 18?
Głównie przez usunięte API: ReactDOM.render, findDOMNode, string refs, przestarzały kontekst (legacy context), propTypes i defaultProps w komponentach funkcyjnych. React 19 wymaga też nowoczesnej transformacji JSX. Najpierw zaktualizuj do React 18.3, popraw jego ostrzeżenia o przestarzałych API, a potem uruchom codemody dla React 19.
Czy do React 19 potrzebuję Next.js?
Nie. Akcje, nowe hooki, ref jako prop i metadane działają w zwykłej aplikacji klienckiej zbudowanej w Vite. Komponenty serwerowe i funkcje serwerowe wymagają frameworka, który je obsługuje, takiego jak Next.js.