React 19: Новые хуки и улучшения работы с формами

React 19, вышедший 5 декабря 2024 года, включает новые хуки и улучшения, упрощающие разработку. Рассмотрим ключевые изменения на практических примерах.

Улучшенная работа с формами: useActionState

Рассмотрим пример формы авторизации, написанной в старом стиле: множество стейтов для загрузки, ошибок и результата, обработка onSubmit с preventDefault.

// Старый стиль
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);

const handleSubmit = (e) => {
  e.preventDefault();
  setIsLoading(true);
  // ... логика отправки запроса ...
};

React 19 предлагает useActionState для упрощения работы с формами. Он позволяет избежать множества отдельных стейтов.

import { useActionState } from 'react-dom';

const handleSubmit = () => {
  // ... логика авторизации ...
};

const { form, submitAction } = useActionState(handleSubmit, { data: null, error: null });

// ... JSX ...
<form onSubmit={submitAction}>
  {/* ... поля формы ... */}
</form>

useActionState возвращает объект form с данными формы и функцию submitAction для отправки. Обработка ошибок и результатов организована следующим образом:

const response = await fakeLogin(form.data.email, form.data.password);

return response ? { data: response } : { error: 'Неверный email или пароль' };

Результат отображается напрямую из form.data и form.error, улучшая читаемость кода.

Отслеживание состояния формы: useFormStatus

Для блокировки кнопки отправки во время загрузки используется хук useFormStatus. Он позволяет отслеживать состояние формы (загрузка, отправка) даже в дочерних компонентах.

import { useFormStatus } from 'react-dom';

const { isSubmitting } = useFormStatus();

// ... JSX ...
<button disabled={isSubmitting}>
  {isSubmitting ? 'Отправка...' : 'Отправить'}
</button>

useFormStatus возвращает объект со статусом формы, включая isSubmitting, позволяя элегантно управлять состоянием кнопки без передачи данных между компонентами.

Оптимистичный рендеринг: useOptimistic

Для мгновенной обратной связи пользователю, даже при обработке запроса на сервере, используется хук useOptimistic.

Рассмотрим пример добавления сообщения. В старом варианте пользователь видит задержку. useOptimistic позволяет немедленно добавить сообщение, помечая его как ожидающее подтверждения от сервера.

import { useOptimistic } from 'react-dom';

const [messages, setMessages] = useState([]);

const optimisticMessages = useOptimistic(
  (prevMessages, newMessage) => [...prevMessages, { ...newMessage, pending: true }],
  []
);

// ... JSX ...
<ul>
  {optimisticMessages.map(msg => (
    <li key={msg.id}>{msg.text} {msg.pending ? '(Adding...)' : ''}</li>
  ))}
</ul>

useOptimistic принимает колбэк для обновления состояния и начальное состояние. Он возвращает обновлённый массив и функцию для добавления элементов. В UI отображаются сообщения, помеченные как ожидающие.

Упрощение работы с промисами: use

React 19 упрощает работу с промисами с помощью метода use. Он позволяет избавиться от useEffect и упростить асинхронные операции.

const users = use(fetchUsers()); // fetchUsers() возвращает Promise

// ... JSX ...
{users.map(user => (
  // ...
))}

Теперь нет необходимости использовать useEffect для обработки промисов. use позволяет напрямую работать с результатом.

Упрощение работы с forwardRef

В React 19 упростилась работа с forwardRef. Теперь нет необходимости оборачивать компоненты в forwardRef для корректной передачи ref.

React 19 привносит существенные улучшения, упрощая разработку и повышая производительность. Новые хуки useActionState, useFormStatus, useOptimistic и упрощение работы с промисами и forwardRef делают код чище и понятнее, сокращая boilerplate код. Это делает разработку на React эффективнее.

Что будем искать? Например,программа