Server Actions (Серверные действия)

Next.js интегрируется с React Actions, предоставляя встроенное решение для серверных мутаций.

Соглашение

Вы можете включить Server Actions в своем проекте Next.js, активировав экспериментальный флаг serverActions.

next.config.js
module.exports = {
  experimental: {
    serverActions: true,
  },
}

Server Actions можно определить в двух местах:

  • Внутри компонента, который их использует (только Server Components).
  • В отдельном файле (для Client и Server Components) для повторного использования. Вы можете определить несколько Server Actions в одном файле.

С Server Components

Создайте Server Action, определив асинхронную функцию с директивой "use server" в начале тела функции. "use server" гарантирует, что эта функция будет выполняться только на сервере.

Эта функция должна иметь сериализуемые аргументы и сериализуемое возвращаемое значение.

app/page.js
export default function ServerComponent() {
  async function myAction() {
    'use server'
    // ...
  }
}

С Client Components

Импорт

Создайте Server Action в отдельном файле с директивой "use server" в начале файла. Затем импортируйте Server Action в ваш Client Component:

app/actions.js
'use server'

export async function myAction() {
  // ...
}
app/client-component.jsx
'use client'

import { myAction } from './actions'

export default function ClientComponent() {
  return (
    <form action={myAction}>
      <button type="submit">Добавить в корзину</button>
    </form>
  )
}

Важно: При использовании директивы "use server" на верхнем уровне все экспорты ниже будут считаться Server Actions. Вы можете иметь несколько Server Actions в одном файле.

Пропсы

В некоторых случаях вам может потребоваться передать Server Action в Client Component как пропс.

<ClientComponent updateItem={updateItem} />
app/client-component.jsx
'use client'

export default function ClientComponent({ myAction }) {
  return (
    <form action={myAction}>
      <input type="text" name="name" />
      <button type="submit">Обновить элемент</button>
    </form>
  )
}

Привязка аргументов

Вы можете привязать аргументы к Server Action с помощью метода bind. Это позволяет создать новую Server Action с уже привязанными аргументами. Это полезно, когда вы хотите передать дополнительные аргументы в Server Action.

app/client-component.jsx
'use client'

import { updateUser } from './actions'

export function UserProfile({ userId }) {
  const updateUserWithId = updateUser.bind(null, userId)

  return (
    <form action={updateUserWithId}>
      <input type="text" name="name" />
      <button type="submit">Обновить имя пользователя</button>
    </form>
  )
}

Затем Server Action updateUser всегда будет получать аргумент userId в дополнение к данным формы:

app/actions.js
'use server'

export async function updateUser(userId, formData) {
  // ...
}

Важно: .bind для Server Action работает как в Server, так и в Client Components. Он также поддерживает Прогрессивное улучшение.

Вызов

Вы можете вызывать Server Actions следующими способами:

  • Используя action: Проп action React позволяет вызывать Server Action на элементе <form>.
  • Используя formAction: Проп formAction React позволяет обрабатывать элементы <button>, <input type="submit"> и <input type="image"> внутри <form>.
  • Пользовательский вызов с startTransition: Вызов Server Actions без использования action или formAction с помощью startTransition. Этот метод отключает Прогрессивное улучшение.

Прогрессивное улучшение

Прогрессивное улучшение позволяет <form> работать корректно без JavaScript или при отключенном JavaScript. Это позволяет пользователям взаимодействовать с формой и отправлять данные, даже если JavaScript для формы еще не загрузился или не смог загрузиться.

React Actions (как серверные, так и клиентские) поддерживают прогрессивное улучшение, используя одну из двух стратегий:

  • Если Server Action передается напрямую в <form>, форма остается интерактивной даже при отключенном JavaScript.
  • Если Client Action передается в <form>, форма также остается интерактивной, но действие будет помещено в очередь до гидратации формы. React приоритезирует это действие, поэтому оно все равно выполняется быстро.

В обоих случаях форма остается интерактивной до гидратации. Хотя Server Actions имеют дополнительное преимущество, не завися от клиентского JavaScript, вы все равно можете комбинировать дополнительное поведение с Client Actions без потери интерактивности.

Ограничение размера

По умолчанию максимальный размер тела запроса, отправляемого в Server Action, составляет 1MB, чтобы предотвратить потребление чрезмерных серверных ресурсов при парсинге больших объемов данных.

Однако вы можете настроить этот лимит с помощью опции serverActionsBodySizeLimit. Она может принимать количество байт или любой строковый формат, поддерживаемый bytes, например 1000, '500kb' или '3mb'.

next.config.js
module.exports = {
  experimental: {
    serverActions: true,
    serverActionsBodySizeLimit: '2mb',
  },
}

Дополнительные ресурсы

Следующие страницы API React в настоящее время документируются:

  • "use server"
  • action (🚧)
  • formAction (🚧)
  • useFormStatus (🚧)
  • useFormState (🚧)
  • useOptimistic (🚧)