React 19, свежая версия известной JavaScript-библиотеки для создания пользовательских интерфейсов, вызывает интерес своим комплексом инструментов и усовершенствований. Чем на самом деле являются эти нововведения: шагом вперёд в производительности и удобстве для разработчиков или очередным витком в "магии" работы с React? В этой статье мы попробуем разобраться в ключевых изменениях, таких как обновления хуков, новые API и функциональность.
Новый хук use
Хук use — один из самых ярких новинок React 19. Он упрощает работу с асинхронными данными и улучшает поддержку серверных компонентов (Server Components). Use примечателен как минимум двумя особенностями:
Помимо этого use может читать данные из контекста:
const message = use(messagePromise);
const theme = use(ThemeContext);
Пример использования в условиях (чтение контекста):
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}
Пример использования use:
import {use} from 'react';
function Comments({commentsPromise}) {
// `use` will suspend until the promise resolves.
const comments = use(commentsPromise);
return comments.map(comment => <p key={comment.id}>{comment}</p>);
}
function Page({commentsPromise}) {
// When `use` suspends in Comments,
// this Suspense boundary will be shown.
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
)
}
use автоматически ожидает выполнения промисов, устраняя необходимость в дополнительных обёртках.
- Во-первых, он может быть использован в условном рендеринге (в отличие от всех своих предшественников, для которых действует строгое правило использования только на верхнем уровне компонента)
- Во-вторых, ожидание промиса для серверных компонентов (этого когда-то не хватало при попытке использовать redux toolkit query в серверном рендеринге)
Помимо этого use может читать данные из контекста:
const message = use(messagePromise);
const theme = use(ThemeContext);
Пример использования в условиях (чтение контекста):
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}
Пример использования use:
import {use} from 'react';
function Comments({commentsPromise}) {
// `use` will suspend until the promise resolves.
const comments = use(commentsPromise);
return comments.map(comment => <p key={comment.id}>{comment}</p>);
}
function Page({commentsPromise}) {
// When `use` suspends in Comments,
// this Suspense boundary will be shown.
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
)
}
use автоматически ожидает выполнения промисов, устраняя необходимость в дополнительных обёртках.
Асинхронный startTransition
Функция startTransition получила обновления, позволяющие теперь работать с асинхронными операциями. Это улучшает управление состояниями в сложных интерфейсах, где важно сохранить отзывчивость приложения.
Как это работает?
Асинхронный startTransition помогает выполнить менее приоритетные задачи, такие как обновления UI, в фоновом режиме, не блокируя важные процессы. Пример:
import { useState, startTransition } from 'react';
function SearchComponent() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const handleSearch = (newQuery) => {
setQuery(newQuery);
startTransition(async () => {
const response = await fetch(`/api/search?q=${newQuery}`);
const data = await response.json();
setResults(data.results);
});
};
return (
<div>
<input
type="text"
value={query}
onChange={(e) => handleSearch(e.target.value)}
/>
<ul>
{results.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
Теперь пользовательский ввод остаётся плавным, даже если асинхронный запрос занимает время.
Как это работает?
Асинхронный startTransition помогает выполнить менее приоритетные задачи, такие как обновления UI, в фоновом режиме, не блокируя важные процессы. Пример:
import { useState, startTransition } from 'react';
function SearchComponent() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const handleSearch = (newQuery) => {
setQuery(newQuery);
startTransition(async () => {
const response = await fetch(`/api/search?q=${newQuery}`);
const data = await response.json();
setResults(data.results);
});
};
return (
<div>
<input
type="text"
value={query}
onChange={(e) => handleSearch(e.target.value)}
/>
<ul>
{results.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
Теперь пользовательский ввод остаётся плавным, даже если асинхронный запрос занимает время.
Новые хуки
React 19 добавляет несколько новых хуков, расширяющих функциональность:
useOptimistic
Этот хук создан для работы с оптимистическими обновлениями. Он позволяет временно изменять состояние приложения, пока операция (например, сетевой запрос) не завершится.
Пример:
import { useOptimistic } from 'react';
function LikeButton({ postId }) {
const [optimisticLikes, addLike] = useOptimistic(0, (likes) => likes + 1);
const handleLike = () => {
addLike();
fetch(`/api/like/${postId}`, { method: 'POST' });
};
return (
<button onClick={handleLike}>
Like ({optimisticLikes})
</button>
);
}
useOptimistic упрощает реализацию временных изменений, устраняя сложность работы с состояниями.
useActionState и useFormStatus
Эти хуки предназначены для работы с серверными действиями и формами.
• useActionState позволяет отслеживать статус действий (например, загрузка, успех или ошибка), которые происходят на сервере. Это полезно при построении интерактивных интерфейсов, где требуется показывать пользователю состояние текущей операции.
• useFormStatus используется для управления состоянием форм, таких как отправка или обработка данных на сервере. Он предоставляет простой способ отслеживать текущий статус формы и обрабатывать ошибки или успешные действия.
Эти хуки дополняют возможности React, делая разработку с использованием серверных действий и форм более интуитивной.
useOptimistic
Этот хук создан для работы с оптимистическими обновлениями. Он позволяет временно изменять состояние приложения, пока операция (например, сетевой запрос) не завершится.
Пример:
import { useOptimistic } from 'react';
function LikeButton({ postId }) {
const [optimisticLikes, addLike] = useOptimistic(0, (likes) => likes + 1);
const handleLike = () => {
addLike();
fetch(`/api/like/${postId}`, { method: 'POST' });
};
return (
<button onClick={handleLike}>
Like ({optimisticLikes})
</button>
);
}
useOptimistic упрощает реализацию временных изменений, устраняя сложность работы с состояниями.
useActionState и useFormStatus
Эти хуки предназначены для работы с серверными действиями и формами.
• useActionState позволяет отслеживать статус действий (например, загрузка, успех или ошибка), которые происходят на сервере. Это полезно при построении интерактивных интерфейсов, где требуется показывать пользователю состояние текущей операции.
• useFormStatus используется для управления состоянием форм, таких как отправка или обработка данных на сервере. Он предоставляет простой способ отслеживать текущий статус формы и обрабатывать ошибки или успешные действия.
Эти хуки дополняют возможности React, делая разработку с использованием серверных действий и форм более интуитивной.
Усовершенствования Suspense
React 19 обновляет функциональность Suspense, добавляя поддержку новых сценариев, таких как загрузка данных на сервере с использованием “use” и асинхронная инициализация данных на клиентской стороне. Это позволяет использовать Suspense для управления состоянием загрузки без необходимости использования сторонних библиотек.
import { Suspense } from 'react';
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<ServerComponent />
</Suspense>
);
}
import { Suspense } from 'react';
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<ServerComponent />
</Suspense>
);
}
Улучшенная поддержка TypeScript
React 19 уделяет больше внимания разработчикам, использующим TypeScript. Обновления включают:
• Более точную типизацию для хуков и компонентов.
• Интеграцию новых API с TypeScript без необходимости дополнительных деклараций.
• Более точную типизацию для хуков и компонентов.
• Интеграцию новых API с TypeScript без необходимости дополнительных деклараций.
Улучшения производительности
React 19 также включает улучшения производительности для клиентских приложений, что делает его ещё быстрее и эффективнее. Оптимизация работы с памятью, уменьшение времени рендеринга и новые подходы к обработке изменений в DOM помогают создавать более отзывчивые интерфейсы.
Заключение
React 19 приносит с собой ряд новшеств, ставших предметом активных обсуждений, которые варьируются от упрощения работы с асинхронными данными до улучшения управления состояниями и повышения производительности. Хук use, асинхронный startTransition и другие новые функции внесли свой вклад в эволюцию библиотеки, хотя и повысили порог освоения для новичков. Эта версия несомненно подходит для проектов, где важны высокая отзывчивость и плавность интерфейсов, но прежде чем принять её на вооружение, стоит задуматься, насколько именно она соответствует нуждам вашего проекта.