Skip to content

React 19: useOptimistic, use(), Server Actions - механізм і архітектура (2026)

React 19 - не інкрементальне оновлення React 18. Він вводить нову модель мутацій - action-based архітектуру - де Server Actions, useOptimistic, useActionState та useFormStatus компонуються у повний патерн серверної мутації, усуваючи reducer + async middleware стек для більшості form-driven та data-mutation UI.

React 19 нові фічі: useOptimistic, use hook, Server Actions - архітектурна діаграма
Опубліковано:Оновлено:Час читання:16 хв

React 19, стабільний з грудня 2024, - найзначніша зміна API surface з часу введення Hooks у 16.8. Реліз вводить п'ять нових примітивів, що разом переключають mutation model React від component-external store патерну (Redux, useState + useEffect + fetch) до action-based моделі, обізнаної про сервер, сумісної з Progressive Enhancement і тісно інтегрованої з concurrent renderer. У цій статті розбираю кожен примітив на рівні механізму - як він працює зсередини і коли застосовувати.

Частина I - useOptimistic та use(): механізми

  • useOptimistic: const [optimisticState, addOptimistic] = useOptimistic(state, updateFn). При виклику addOptimistic(value) React застосовує updateFn(currentState, value) під час рендерингу для обчислення оптимістичного стану. При помилці action - автоматичний rollback до state до виклику addOptimistic. Кілька конкурентних оптимістичних оновлень застосовуються по порядку з незалежною обробкою помилок.
  • use(promise) - Suspense-інтеграція у Client Components: const data = use(promise). Якщо Promise pending - React призупиняє компонент. На відміну від useEffect + useState, немає проміжного рендерингу з null. Server Component ініціює fetch (не await-ить), передає Promise у Client Component; Client Component викликає use(promise).
  • use(context) - умовний доступ до Context: Може бути викликаний усередині conditional-блоків - неможливо з useContext. if (isAdmin) { const config = use(AdminContext); } - тепер валідний патерн.

Частина II - Server Actions та useActionState

  • Server Actions - механізм: Next.js присвоює кожній 'use server'-функції унікальний action ID. Клієнт відправляє HTTP POST з action ID; сервер виконує функцію. CSRF-захист вбудований автоматично. Progressive Enhancement: <form action={serverAction}> працює без JavaScript.
  • Безпека: Аргументи Server Action - контрольовані користувачем дані HTTP POST. Завжди валідувати server-side: const user = await getSession(); if (item.userId !== user.id) throw new Error('Unauthorized');
  • useActionState (перейменований з useFormState): const [state, dispatch, isPending] = useActionState(action, initialState). Action: (previousState, formData) => Promise<newState>. isPending: true поки action виконується. Замінює useState + setLoading патерн.
  • useFormStatus: const { pending } = useFormStatus(). Читає статус найближчої батьківської <form>. Має викликатися у компоненті-нащадку форми. <SubmitButton> патерн без prop drilling.

Частина III - Синтаксичні зміни та Action-based архітектура

  • ref як prop (forwardRef застарів): function Input({ ref, ...props }) { return <input ref={ref} {...props} />; } без forwardRef.
  • Context як provider: <ThemeContext value={theme}> замість <ThemeContext.Provider value={theme}>.
  • Повна компоновка mutation патерну: (1) Server Action; (2) useActionState - persistent state + isPending; (3) useOptimistic - миттєвий UI-відгук; (4) useFormStatus у <SubmitButton>. Ці чотири примітиви замінюють Zustand store з loading + error + optimistic + fetch у useEffect + try/catch rollback.
  • PPR + useOptimistic: PPR обслуговує статичний shell з CDN; dynamic holes - інтерактивні острівці з useOptimistic. Детальніше - у гайді з PPR.
  • Приклад Add to Cart (headless Shopify): const [cart, addToCart, isPending] = useActionState(addToCartAction, initial); const [optimisticCart, addOptimistic] = useOptimistic(cart, (s, line) => ({ ...s, lines: [...s.lines, line] }));. Архітектурний контекст - у гайді з headless Shopify.

Частина IV - Міграція React 18 → 19

  • useFormStateuseActionState: перейменований, перенесений з react-dom у react, доданий isPending третім значенням.
  • ReactDOM.render та ReactDOM.hydrate видалені: замінити на createRoot та hydrateRoot.
  • TypeScript: оновити @types/react до 19.x. Ref-prop у function components без forwardRef.
  • Метадані документа: <title>, <meta>, <link> у компонентах - автоматичний hoisting у <head>.
  • Asset preloading API: import { preload, preconnect, prefetchDNS } from 'react-dom'.

Висновок

React 19 - узгоджена архітектурна концепція: мутації описуються як дії, а фреймворк управляє async-циклом. Для команд на Next.js App Router action model та Server Actions - призначена mutation архітектура. Для архітектурного ревʼю або реалізації - сервіс React SPA development | кейси | обговорити проект.

Джерела

Схожі статті

Partial Prerendering (PPR) у продакшні: архітектурні патерни (2026)

Детальний розбір Next.js Partial Prerendering у продакшні. Механізм двофазної відповіді, правила розміщення Suspense-меж, взаємодія з Full Route Cache, дизайн fallback для нульового CLS, виміряні TTFB/LCP, порівняння з ISR+CSR та full SSR і фреймворк прийняття рішень.

Next.jsPerformancePPR
Читати статтю

Міграція на Next.js App Router з Pages Router: повний практичний гайд (2026)

Практичний гайд з міграції продакшн-застосунків Next.js з Pages Router на App Router. Вартісна модель гідратації RSC, механіка модульного графа webpack і директиви 'use client', внутрішній устрій Data Cache, інкрементальна стратегія, розбір типових помилок і фреймворк прийняття рішень.

Next.jsArchitectureMigration
Читати статтю

Shopify Hydrogen vs Next.js Commerce: яку архітектуру обрати для магазину у 2026

Детальне порівняння двох основних headless-архітектур для Shopify. Модель виконання, шар даних, стратегія кешування, розмір бандлу, бенчмарки продуктивності (LCP/INP/CLS), TCO, ризик вендор-локіну та практичний фреймворк рішень між нативною глибиною Hydrogen та компонованою гнучкістю Next.js Commerce.

eCommerceNext.jsShopify
Читати статтю