Acciones del Servidor (Server Actions)

Next.js se integra con Acciones de React para proporcionar una solución incorporada para mutaciones del servidor.

Convención

Puedes habilitar Acciones del Servidor en tu proyecto Next.js activando la bandera experimental serverActions.

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

Las Acciones del Servidor pueden definirse en dos lugares:

  • Dentro del componente que las utiliza (solo Componentes del Servidor).
  • En un archivo separado (Componentes del Cliente y del Servidor), para reutilización. Puedes definir múltiples Acciones del Servidor en un solo archivo.

Con Componentes del Servidor

Crea una Acción del Servidor definiendo una función asíncrona con la directiva "use server" al inicio del cuerpo de la función. "use server" asegura que esta función solo se ejecute en el servidor.

Esta función debe tener argumentos serializables y un valor de retorno serializable.

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

Con Componentes del Cliente

Importación

Crea tu Acción del Servidor en un archivo separado con la directiva "use server" al inicio del archivo. Luego, importa la Acción del Servidor en tu Componente del Cliente:

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">Añadir al carrito</button>
    </form>
  )
}

Nota importante: Cuando se usa la directiva "use server" al nivel superior, todas las exportaciones debajo serán consideradas Acciones del Servidor. Puedes tener múltiples Acciones del Servidor en un solo archivo.

Props

En algunos casos, es posible que desees pasar una Acción del Servidor a un Componente del Cliente como prop.

<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">Actualizar elemento</button>
    </form>
  )
}

Vinculación de Argumentos

Puedes vincular argumentos a una Acción del Servidor usando el método bind. Esto te permite crear una nueva Acción del Servidor con algunos argumentos ya vinculados. Esto es beneficioso cuando deseas pasar argumentos adicionales a una Acción del Servidor.

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">Actualizar nombre de usuario</button>
    </form>
  )
}

Y luego, la Acción del Servidor updateUser siempre recibirá el argumento userId, además de los datos del formulario:

app/actions.js
'use server'

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

Nota importante: El .bind de una Acción del Servidor funciona tanto en Componentes del Servidor como del Cliente. También soporta Mejora Progresiva.

Invocación

Puedes invocar Acciones del Servidor usando los siguientes métodos:

  • Usando action: La prop action de React permite invocar una Acción del Servidor en un elemento <form>.
  • Usando formAction: La prop formAction de React permite manejar elementos <button>, <input type="submit"> y <input type="image"> en un <form>.
  • Invocación personalizada con startTransition: Invoca Acciones del Servidor sin usar action o formAction mediante startTransition. Este método deshabilita la Mejora Progresiva.

Mejora Progresiva

La mejora progresiva permite que un <form> funcione correctamente sin JavaScript, o con JavaScript deshabilitado. Esto permite a los usuarios interactuar con el formulario y enviar datos incluso si el JavaScript del formulario no se ha cargado aún o si falla al cargar.

Las Acciones de React (tanto del servidor como del cliente) soportan mejora progresiva, usando una de dos estrategias:

  • Si se pasa una Acción del Servidor directamente a un <form>, el formulario es interactivo incluso si JavaScript está deshabilitado.
  • Si se pasa una Acción del Cliente a un <form>, el formulario sigue siendo interactivo, pero la acción se colocará en una cola hasta que el formulario se haya hidratado. React prioriza la acción, por lo que aún ocurre rápidamente.

En ambos casos, el formulario es interactivo antes de que ocurra la hidratación. Aunque las Acciones del Servidor tienen el beneficio adicional de no depender del JavaScript del cliente, aún puedes componer comportamiento adicional con Acciones del Cliente donde se desee sin sacrificar la interactividad.

Límite de Tamaño

Por defecto, el tamaño máximo del cuerpo de la solicitud enviado a una Acción del Servidor es de 1MB, para evitar el consumo excesivo de recursos del servidor al analizar grandes cantidades de datos.

Sin embargo, puedes configurar este límite usando la opción serverActionsBodySizeLimit. Puede tomar el número de bytes o cualquier formato de cadena soportado por bytes, por ejemplo 1000, '500kb' o '3mb'.

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

Recursos Adicionales

Las siguientes páginas de API de React están actualmente siendo documentadas:

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