React Concurrent Features
Suspense, useTransition (isPending), useDeferredValue (stale UI), automatic batching, use() hook i useOptimistic React 19.
6 Concurrent React features — zastosowanie i efekt
Suspense, useTransition, useDeferredValue, batching, use() i useOptimistic — kiedy i co daje.
| Funkcja | Kiedy | Efekt |
|---|---|---|
| Suspense + lazy() | Lazy loading komponentów i data fetching | Code splitting, fallback UI, streaming SSR |
| useTransition | Masz kontrolę nad setState, heavy renders | isPending, UI nie blokuje, stara zawartość |
| useDeferredValue | Wartość z props, expensive children | Background render, stale indicator, memo |
| Automatic batching | Zawsze w React 18+ (setTimeout, fetch) | Mniej re-renderów, wydajność |
| use() hook (React 19) | Promise lub Context w warunkach | Conditional async, Suspense integration |
| useOptimistic (React 19) | Mutacje z natychmiastowym feedback | Optimistic UI, rollback przy błędzie |
Często zadawane pytania
React Concurrent Mode — co to znaczy i jak działa Fiber?
Concurrent React (React 18+): możliwość przerwania renderowania. Priorytety zadań. Bez blokowania UI. Nie jest 'tryb' — to zestaw funkcji. React Fiber: wewnętrzna architektura od React 16. Podział pracy na małe jednostki (fibers). Możliwość przerwania, wznowienia, porzucenia. Drzewo Fiber: każdy komponent to fiber node. Dwa drzewa: current (wyświetlone) i work-in-progress. Double buffering. Reconciliation: różni się od DOM. Virtual DOM comparison. Keyed list — stable identity. Priority lanes: SyncLane — natychmiastowe (kliknięcia, input). InputContinuousLane — scroll, hover. DefaultLane — normalne setState. TransitionLane — useTransition. IdleLane — offscreen. React Scheduler: harmonogram pracy. requestIdleCallback-like. Yield do przeglądarki co 5ms. Nie blokuj main thread. createRoot: obowiązkowy dla Concurrent: ReactDOM.createRoot(document.getElementById('root')).render(App /). Włącza concurrent features. Nie ma render(). Automatic batching: React 18 automatycznie batchuje wszystkie setState. Nawet w setTimeout, fetch callbacks. Wcześniej tylko w event handlers. flushSync: wymuś synchroniczny render. flushSync(() => setState(value)). Dla DOM measurements. Rzadko potrzebne.
Suspense i use() — data fetching i lazy loading w React 18?
Suspense: boundary dla async operacji. fallback — wyświetlany gdy czeka. Lazy loading: const MyComponent = lazy(() => import('./MyComponent')). Suspense fallback={Loading /} MyComponent /. Plik ładowany on-demand. Code splitting. React 19 use() hook: const value = use(promise). Może być w if/for/while. Nie jak useState. Suspense integracja: use(fetchData()) — Suspense wychwytuje. Fallback podczas fetch. ErrorBoundary dla błędów. TanStack Query + Suspense: useSuspenseQuery. Rzuca Promise gdy loading. Rzuca Error gdy błąd. Cleaner code. const {data} = useSuspenseQuery({queryKey: ['users'], queryFn: fetchUsers}). Zagnieżdżone Suspense: każdy może mieć własny fallback. Granular loading states. SuspenseList: koordynacja wielu Suspense. order: 'forwards' | 'backwards' | 'together'. Unikaj popping. React 19: Suspense na Server Components. SSR streaming z Suspense. defer w Remix. startTransition + Suspense: smooth transition. Stara zawartość widoczna podczas ładowania. Skeleton UI bez flickering. Nie-data Suspense: Image lazy loading. Route lazy. Feature lazy (Suspense + flag). Selective Hydration: SSR + Suspense. Najważniejsze komponenty hydrowane pierwsze. User interaction hydruje priorytetowo. Pre-renders rest. Concurrent features + Suspense: wielka siła. UI zawsze responsive. Streaming SSR. Incremental hydration.
useTransition i startTransition — nie-pilne aktualizacje?
useTransition: oznacz aktualizacje jako nie-pilne. UI responsywne podczas heavy render. Podstawy: const [isPending, startTransition] = useTransition(). function handleClick() { startTransition(() => { setFilter(newFilter) }) }. {isPending && div class='opacity-50' /}. Jak działa: startTransition wewnątrz = niski priorytet. React może przerwać. Inne aktualizacje (input) mają pierwszeństwo. Render filter nie blokuje typing. Przykład z listą: input onChange={(e) => { setInput(e.target.value). startTransition(() => { setQuery(e.target.value) }) }}. Typing natychmiastowy. Filtrowanie nie blokuje. isPending: true gdy w trakcie. Pokaż loading indicator. Nie unmount! Stara zawartość widoczna. startTransition (bez hook): import {startTransition} from 'react'. Bez isPending. Dla poza-komponentów. Router nawigacja. Przykład React Router: startTransition(() => { navigate('/new-page') }). Smooth navigation. Loader podczas transition. React 19 zmiany: Server Actions = automatyczny startTransition. useActionState — isPending wbudowany. React 19 form submit. useTransition vs setTimeout: setTimeout — hack. useTransition — semantyczny. React rozumie intencje. useTransition vs useDeferredValue: useTransition — masz kontrolę nad setter. useDeferredValue — masz tylko wartość (props). Używaj useTransition gdy możesz. useDeferredValue gdy props z rodzica. Throttle nie jest potrzebny — React sam zarządza.
useDeferredValue — odroczone wartości dla expensive renders?
useDeferredValue: opóźnij synchronizację wartości. Dla expensive children. Bez kontroli nad setter. const deferredQuery = useDeferredValue(query). Wyniki renderowania z opóźnieniem. Input natychmiastowy. Jak działa: deferredQuery 'stara' wartość podczas typing. React renderuje z 'nową' gdy main thread wolny. Background render — przerywany gdy nowy input. Przykład: function SearchResults({query}: {query: string}) { const deferredQuery = useDeferredValue(query). const results = useMemo(() => expensiveSearch(deferredQuery), [deferredQuery]). return div {results.map(...)} /div }. Wskazanie stale: const isStale = query !== deferredQuery. div class={isStale ? 'opacity-50' : ''}. Opacity gdy nieaktualne. useMemo wymagany: useDeferredValue + useMemo = optymalizacja. Bez useMemo — każdy render przelicza. useDeferredValue memoizuje trigger. React.memo na dzieciach: const ExpensiveList = React.memo(({query}) => ...}). Deferred value + memo = max optimization. Porównanie useTransition vs useDeferredValue: useTransition — owinij setter. useDeferredValue — owinij wartość. useTransition: setState wewnątrz startTransition. useDeferredValue: const d = useDeferredValue(value). Oba: background render, responsywny UI. Razem: useTransition dla nawigacji. useDeferredValue dla search. Nie mieszaj — wybierz jedno. useDeferredValue v/s debounce: debounce — opóźnia przez czas. useDeferredValue — opóźnia przez priorytety. useDeferredValue natychmiastowy gdy CPU wolny. Debounce zawsze czeka.
useId, useInsertionEffect i inne React 18+ hooks?
useId: generuje stabilne, unikalne ID. Server i client match (hydration safe). const id = useId(). input id={id}. label htmlFor={id}. Wcześniej: Math.random() — mismatch. index — zmienny. useId: deterministyczny. Wiele w jednym komponencie: const id = useId(). const nameId = id + '-name'. const emailId = id + '-email'. Prefix: id + ':r0:'. Unikalne globalnie. useInsertionEffect: dla CSS-in-JS bibliotek. Przed DOM mutations. Przed useLayoutEffect. Pobieranie CSS rules. Emotion, styled-components użyją. Normalny dev nie potrzebuje. useLayoutEffect vs useEffect: useLayoutEffect — synchroniczny, przed paint. Mierzenie DOM size. Scroll position. Tooltips pozycjonowanie. useEffect — asynchroniczny, po paint. Fetch. Event listeners. useSyncExternalStore: subscribe do zewnętrznego store. Browser APIs. Redux. Zustand. const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot). Bezpieczny z Concurrent. useDebugValue: custom hook debug info. DevTools widoczność. useDebugValue(isOnline ? 'Online' : 'Offline'). useFormStatus (React 19): const {pending, data, method, action} = useFormStatus(). W dziecku form. Automatyczny isPending. useOptimistic (React 19): const [optimisticState, addOptimistic] = useOptimistic(state, reducer). Natychmiastowy feedback. Rollback przy błędzie. use (React 19): use(Promise) lub use(Context). Może być w warunkach. Zastępuje useContext w if.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz