React 19.1.8: что скрывается за патчем Server Actions

#react#server-components#formdata

Когда в changelog попадает всего одна строка, это либо тривиальный багфикс, либо подводный камень для тех, кто не читает исходники. Регрессия FormData в Server Actions из 19.1.7 — определённо второй случай. Вот что я выяснил, разбирая этот патч.

Server Actions: когда FormData теряет записи

В 19.1.7 незаметно закрался баг: отправка форм через Server Actions могла терять часть FormData entries. Проблема проявлялась не всегда — только при определённых условиях сериализации. На практике это означало, что:

// Клиентский компонент
<form action={serverAction}>
  <input name="file" type="file" />
  <input name="metadata" value={JSON.stringify(data)} />
</form>

// Server Action
async function serverAction(formData: FormData) {
  // В 19.1.7 formData.get('metadata') мог вернуть null
  const meta = JSON.parse(formData.get('metadata')); // 💥
}

Фикс в 19.1.8 исправляет проблему с сериализацией мультипарт-форм, но сам инцидент показывает хрупкость Server Actions API. Это особенно критично для гибридных форм, где смешиваются файлы и JSON-метаданные.

Почему это важно для RSC workflows

Проблема не выглядела бы такой серьёзной, если бы не растущая зависимость от Server Components. В современных RSC-приложениях Server Actions часто становятся единственным способом:

  1. Отправлять файлы без custom API routes
  2. Интегрироваться с storage-провайдерами (S3, Cloud Storage)
  3. Работать с edge-функциями через промежуточные метаданные

Баги в FormData ломают все три сценария. По факту, 19.1.7 мог испортить продакшен-деплой с файловыми загрузками — и хорошо, что фикс выпустили через 4 дня.

Что проверить после апгрейда

Для тех, кто уже обновился до 19.1.8, рекомендую провести два теста:

  1. Гибридные формы — отправку форм, где сочетаются type="file" и сложные текстовые поля:
// Проверяем, что nested JSON не ломается
<form action={uploadAction}>
  <input type="file" name="documents" multiple />
  <input type="hidden" name="context" value={JSON.stringify({ user: user.id })} />
</form>
  1. Большие файлы — если ваш обработчик использует form-data-парсеры вроде busboy, убедитесь, что стриминг работает как раньше.

Особенно внимательными стоит быть тем, кто использует Server Actions вместе с React Compiler (прежнее название React Forget). Некоторые рантайм-оптимизации пока плохо сочетаются с мультипарт-формами.

Server Components как moving target

Этот патч — хороший повод вспомнить, что React Server Components всё ещё в активной разработке. Фичи, которые вчера работали, могут сломаться в минорном обновлении. В данном случае проблема была в internals — глубоко в сериализации между клиентом и сервером.

Что делать:

Если вы уже наступили на этот баг в 19.1.7 — проверьте логи обработчиков на предмет null или undefined вместо ожидаемых formData entries. В большинстве случаев апгрейд решит проблему, но данные могли сохраниться с ошибками.


Попробуй сам: DigitalOcean — $200 кредитов для новых пользователей.


Источник: https://github.com/facebook/react/releases/tag/v19.1.8