Изучите React Server Actions — мощную функцию для обработки форм и изменения данных прямо на сервере, упрощающую разработку на React и повышающую безопасность.
Действия на сервере в React: Упрощенная обработка форм на стороне сервера
Действия на сервере в React (React Server Actions), представленные в React 18 и значительно улучшенные в Next.js, предлагают революционный подход к обработке отправки форм и мутаций данных непосредственно на сервере. Эта мощная функция упрощает процесс разработки, повышает безопасность и улучшает производительность по сравнению с традиционными методами получения и обработки данных на стороне клиента.
Что такое React Server Actions?
Действия на сервере — это асинхронные функции, которые выполняются на сервере и могут быть вызваны непосредственно из компонентов React. Они позволяют выполнять задачи на стороне сервера, такие как:
- Отправка форм: Безопасная обработка данных форм на сервере.
- Мутации данных: Обновление баз данных или внешних API.
- Аутентификация: Обработка входа и регистрации пользователей.
- Серверная логика: Выполнение сложной бизнес-логики без раскрытия ее на клиенте.
Ключевое преимущество Server Actions заключается в том, что они позволяют писать серверный код внутри ваших компонентов React, устраняя необходимость в отдельных маршрутах API и сложной логике получения данных на стороне клиента. Такое совмещение UI и серверной логики приводит к более поддерживаемому и эффективному коду.
Преимущества использования React Server Actions
Использование React Server Actions дает несколько значительных преимуществ:
Упрощенная разработка
Server Actions сокращают количество шаблонного кода, позволяя обрабатывать отправку форм и мутации данных непосредственно в ваших компонентах React. Это устраняет необходимость в отдельных конечных точках API и сложной логике получения данных на стороне клиента, оптимизируя процесс разработки и делая ваш код более понятным и простым в обслуживании. Рассмотрим простую контактную форму. Без Server Actions вам потребовался бы отдельный маршрут API для обработки отправки формы, JavaScript на стороне клиента для отправки данных и логика обработки ошибок как на клиенте, так и на сервере. С помощью Server Actions все это можно обработать внутри самого компонента.
Повышенная безопасность
Выполняя код на сервере, Server Actions уменьшают поверхность атаки вашего приложения. Конфиденциальные данные и бизнес-логика хранятся вдали от клиента, что не позволяет злоумышленникам вмешиваться в них. Например, учетные данные базы данных или ключи API никогда не раскрываются в коде на стороне клиента. Все взаимодействия с базой данных происходят на сервере, что снижает риск SQL-инъекций или несанкционированного доступа к данным.
Улучшенная производительность
Server Actions могут повысить производительность за счет уменьшения объема JavaScript, который необходимо загружать и выполнять на клиенте. Это особенно полезно для пользователей на маломощных устройствах или с медленным интернет-соединением. Обработка данных происходит на сервере, и клиенту отправляются только необходимые обновления пользовательского интерфейса, что приводит к более быстрой загрузке страниц и более плавному взаимодействию с пользователем.
Оптимистичные обновления
Server Actions легко интегрируются с Suspense и Transitions в React, позволяя выполнять оптимистичные обновления. Оптимистичные обновления позволяют немедленно обновлять пользовательский интерфейс, даже до того, как сервер подтвердит действие. Это обеспечивает более отзывчивый и привлекательный пользовательский опыт, так как пользователям не нужно ждать ответа сервера, чтобы увидеть результаты своих действий. В электронной коммерции добавление товара в корзину может отображаться немедленно, пока сервер подтверждает добавление в фоновом режиме.
Прогрессивное улучшение
Server Actions поддерживают прогрессивное улучшение, что означает, что ваше приложение может продолжать работать, даже если JavaScript отключен или не загрузился. Когда JavaScript отключен, формы будут отправляться как традиционные HTML-формы, и сервер обработает отправку и перенаправит пользователя на новую страницу. Это гарантирует, что ваше приложение останется доступным для всех пользователей, независимо от конфигурации их браузера или условий сети. Это особенно важно для доступности и SEO.
Как использовать React Server Actions
Чтобы использовать React Server Actions, вам нужно использовать фреймворк, который их поддерживает, например, Next.js. Вот пошаговое руководство:
1. Определение действия на сервере
Создайте асинхронную функцию, которая будет выполняться на сервере. Эта функция должна обрабатывать логику, которую вы хотите выполнить на сервере, например, обновление базы данных или вызов API. Пометьте функцию директивой `"use server"` вверху, чтобы указать, что это действие на сервере. Эта директива указывает компилятору React рассматривать функцию как серверную и автоматически обрабатывать сериализацию и десериализацию данных между клиентом и сервером.
// app/actions.js
'use server'
import { revalidatePath } from 'next/cache';
import { saveMessage } from './db';
export async function createMessage(prevState, formData) {
const message = formData.get('message');
try {
await saveMessage(message);
revalidatePath('/'); // Очистить кеш маршрута
return { message: 'Сообщение успешно сохранено!' };
} catch (e) {
return { message: 'Не удалось сохранить сообщение' };
}
}
Пояснение:
- Директива `'use server'` помечает эту функцию как действие на сервере (Server Action).
- `revalidatePath('/')` очищает кеш маршрута, гарантируя, что обновленные данные будут получены при следующем запросе. Это крайне важно для поддержания согласованности данных.
- `saveMessage(message)` — это заглушка для вашей реальной логики взаимодействия с базой данных. Предполагается, что у вас есть функция `saveMessage`, определенная в другом месте для сохранения сообщения в вашей базе данных.
- Функция возвращает объект состояния, который можно использовать для отображения обратной связи пользователю.
2. Импорт и использование действия на сервере в вашем компоненте
Импортируйте действие на сервере в ваш компонент React и используйте его в качестве пропа `action` элемента формы. Хук `useFormState` можно использовать для управления состоянием формы и отображения обратной связи пользователю.
// app/page.jsx
'use client';
import { useFormState } from 'react-dom';
import { createMessage } from './actions';
export default function Home() {
const [state, formAction] = useFormState(createMessage, {message: ''});
return (
);
}
Пояснение:
- Директива `'use client'` указывает, что это клиентский компонент (поскольку он использует `useFormState`).
- `useFormState(createMessage, {message: ''})` инициализирует состояние формы с помощью действия на сервере `createMessage`. Второй аргумент — это начальное состояние.
- Проп `action` элемента `form` устанавливается в `formAction`, возвращаемый `useFormState`.
- Переменная `state` содержит возвращаемое значение из действия на сервере, которое можно использовать для отображения обратной связи пользователю.
3. Обработка данных формы
Внутри действия на сервере вы можете получить доступ к данным формы с помощью API `FormData`. Этот API предоставляет удобный способ доступа к значениям полей формы.
'use server'
export async function createMessage(prevState, formData) {
const message = formData.get('message');
// ...
}
4. Обработка ошибок
Используйте блоки `try...catch` для обработки ошибок, которые могут возникнуть во время выполнения действия на сервере. Возвращайте сообщение об ошибке в объекте состояния, чтобы отобразить его пользователю.
'use server'
export async function createMessage(prevState, formData) {
const message = formData.get('message');
try {
// ...
} catch (e) {
return { message: 'Не удалось сохранить сообщение' };
}
}
5. Ревалидация данных
После того, как действие на сервере успешно изменило данные, вам может потребоваться ревалидировать кеш данных, чтобы убедиться, что пользовательский интерфейс отражает последние изменения. Используйте функции `revalidatePath` или `revalidateTag` из `next/cache` для ревалидации определенных путей или тегов.
'use server'
import { revalidatePath } from 'next/cache';
export async function createMessage(prevState, formData) {
// ...
revalidatePath('/'); // Очистить кеш маршрута
// ...
}
Продвинутое использование
Изменение данных
Действия на сервере особенно хорошо подходят для изменения данных, таких как обновление баз данных или внешних API. Вы можете использовать Server Actions для обработки сложных мутаций данных, требующих серверной логики, такой как проверка данных, выполнение вычислений или взаимодействие с несколькими источниками данных. Рассмотрим сценарий, в котором вам нужно обновить профиль пользователя и отправить подтверждающее письмо. Действие на сервере может обработать как обновление базы данных, так и отправку письма в одной атомарной операции.
Аутентификация и авторизация
Действия на сервере можно использовать для аутентификации и авторизации. Выполняя проверки аутентификации и авторизации на сервере, вы можете гарантировать, что только авторизованные пользователи имеют доступ к конфиденциальным данным и функциональности. Вы можете использовать Server Actions для обработки входа пользователей, регистрации и сброса пароля. Например, действие на сервере может проверить учетные данные пользователя в базе данных и вернуть токен, который можно использовать для аутентификации последующих запросов.
Edge-функции
Действия на сервере могут быть развернуты как Edge-функции, которые выполняются в глобальной сети серверов, близких к вашим пользователям. Это может значительно сократить задержку и повысить производительность, особенно для пользователей в географически удаленных местах. Edge-функции идеально подходят для обработки Server Actions, требующих низкой задержки, таких как обновления данных в реальном времени или доставка персонализированного контента. Next.js предоставляет встроенную поддержку для развертывания Server Actions в виде Edge-функций.
Стриминг (потоковая передача)
Действия на сервере поддерживают стриминг, что позволяет отправлять данные клиенту по частям по мере их доступности. Это может улучшить воспринимаемую производительность вашего приложения, особенно для Server Actions, выполнение которых занимает много времени. Стриминг особенно полезен для обработки больших наборов данных или сложных вычислений. Например, вы можете передавать результаты поиска клиенту по мере их извлечения из базы данных, обеспечивая более отзывчивый пользовательский опыт.
Лучшие практики
Вот некоторые лучшие практики, которым следует придерживаться при использовании React Server Actions:
- Делайте Server Actions небольшими и сфокусированными: Каждое действие на сервере должно выполнять одну, четко определенную задачу. Это делает ваш код более понятным, тестируемым и простым в обслуживании.
- Используйте описательные имена: Выбирайте имена, которые четко указывают на назначение действия на сервере. Например, `createComment` или `updateUserProfile` лучше, чем общие имена, такие как `processData`.
- Проверяйте данные на сервере: Всегда проверяйте данные на сервере, чтобы предотвратить внедрение неверных данных в ваше приложение злоумышленниками. Это включает проверку типов данных, форматов и диапазонов.
- Грамотно обрабатывайте ошибки: Используйте блоки `try...catch` для обработки ошибок и предоставления информативных сообщений об ошибках пользователю. Избегайте раскрытия конфиденциальной информации об ошибках на клиенте.
- Используйте оптимистичные обновления: Обеспечьте более отзывчивый пользовательский опыт, немедленно обновляя пользовательский интерфейс, даже до того, как сервер подтвердит действие.
- Ревалидируйте данные по мере необходимости: Убедитесь, что пользовательский интерфейс отражает последние изменения, ревалидируя кеш данных после того, как действие на сервере изменило данные.
Примеры из реального мира
Рассмотрим несколько реальных примеров того, как React Server Actions можно использовать в различных типах приложений:
Приложение для электронной коммерции
- Добавление товара в корзину: Действие на сервере может обработать добавление товара в корзину пользователя и обновить общую сумму в базе данных. Оптимистичные обновления можно использовать для немедленного отображения товара в корзине.
- Обработка платежа: Действие на сервере может обработать платеж с использованием стороннего платежного шлюза. Действие на сервере также может обновить статус заказа в базе данных и отправить подтверждающее письмо пользователю.
- Отправка отзыва о товаре: Действие на сервере может обработать отправку отзыва о товаре и сохранить его в базе данных. Действие на сервере также может рассчитать средний рейтинг товара и обновить страницу сведений о товаре.
Приложение для социальных сетей
- Публикация нового твита: Действие на сервере может обработать публикацию нового твита и сохранить его в базе данных. Действие на сервере также может обновить ленту пользователя и уведомить его подписчиков.
- Лайк поста: Действие на сервере может обработать лайк поста и обновить количество лайков в базе данных. Оптимистичные обновления можно использовать для немедленного отображения обновленного количества лайков.
- Подписка на пользователя: Действие на сервере может обработать подписку на пользователя и обновить количество подписчиков и подписок в базе данных.
Система управления контентом (CMS)
- Создание нового поста в блоге: Действие на сервере может обработать создание нового поста в блоге и сохранить его в базе данных. Действие на сервере также может сгенерировать слаг для поста и обновить карту сайта.
- Обновление страницы: Действие на сервере может обработать обновление страницы и сохранить его в базе данных. Действие на сервере также может ревалидировать кеш страницы, чтобы обновленный контент отображался пользователям.
- Публикация изменения: Действие на сервере может обработать публикацию изменения в базе данных и уведомить всех подписчиков.
Вопросы интернационализации
При разработке приложений для глобальной аудитории важно учитывать интернационализацию (i18n) и локализацию (l10n). Вот некоторые соображения по использованию React Server Actions в интернационализированных приложениях:
- Обработка различных форматов даты и времени: Используйте API `Intl` для форматирования дат и времени в соответствии с локалью пользователя.
- Обработка различных числовых форматов: Используйте API `Intl` для форматирования чисел в соответствии с локалью пользователя.
- Обработка различных валют: Используйте API `Intl` для форматирования валют в соответствии с локалью пользователя.
- Перевод сообщений об ошибках: Переводите сообщения об ошибках на язык пользователя.
- Поддержка языков с письмом справа налево (RTL): Убедитесь, что ваше приложение поддерживает языки RTL, такие как арабский и иврит.
Например, при обработке формы, требующей ввода даты, действие на сервере может использовать API `Intl.DateTimeFormat` для разбора даты в соответствии с локалью пользователя, гарантируя, что дата будет правильно интерпретирована независимо от региональных настроек пользователя.
Заключение
React Server Actions — это мощный инструмент для упрощения обработки форм на стороне сервера и мутаций данных в приложениях React. Позволяя писать серверный код непосредственно в ваших компонентах React, Server Actions сокращают количество шаблонного кода, повышают безопасность, улучшают производительность и позволяют выполнять оптимистичные обновления. Следуя лучшим практикам, изложенным в этом руководстве, вы можете использовать Server Actions для создания более надежных, масштабируемых и поддерживаемых приложений React. По мере развития React, Server Actions, несомненно, будут играть все более важную роль в будущем веб-разработки.