React Server Components

'use server' deve ser usado com usando React Server Components.

'use server' marca funções do lado do servidor que podem ser chamadas a partir do código do lado do cliente.


Referência

'use server'

Adicione 'use server' no início do corpo de uma função async para marcar a função como chamável pelo cliente. Chamamos essas funções de Funções do Servidor.

async function addToCart(data) {
'use server';
// ...
}

Ao chamar uma Server Function no cliente, ela fará uma requisição de rede ao servidor que inclui uma cópia serializada de quaisquer argumentos passados. Se a Server Function retornar um valor, esse valor será serializado e retornado ao cliente.

Em vez de marcar funções individualmente com 'use server', você pode adicionar a diretiva no topo de um arquivo para marcar todas as exportações dentro desse arquivo como Server Functions que podem ser usadas em qualquer lugar, inclusive importadas no código do cliente.

Ressalvas

  • 'use server' deve estar no início da função ou módulo; acima de qualquer outro código, incluindo imports (comentários acima das diretivas são OK). Elas devem ser escritas com aspas simples ou duplas, não crases.
  • 'use server' só pode ser usado em arquivos do lado do servidor. As Server Functions resultantes podem ser passadas para Client Components por meio de props. Veja os tipos suportados para serialização.
  • Para importar Server Functions do código do cliente, a diretiva deve ser usada em nível de módulo.
  • Como as chamadas de rede subjacentes são sempre assíncronas, 'use server' só pode ser usado em funções async.
  • Sempre trate os argumentos das Server Functions como entrada não confiável e autorize quaisquer mutações. Veja considerações de segurança.
  • As Server Functions devem ser chamadas em uma Transition. Server Functions passadas para <form action> ou formAction serão automaticamente chamadas em uma transition.
  • As Server Functions são projetadas para mutações que atualizam o estado do lado do servidor; não são recomendadas para busca de dados. Consequentemente, frameworks que implementam Server Functions normalmente processam uma ação por vez e não têm uma maneira de armazenar em cache o valor de retorno.

Considerações de segurança

Os argumentos das Server Functions são totalmente controlados pelo cliente. Para segurança, sempre trate-os como entrada não confiável e certifique-se de validar e escapar dos argumentos conforme apropriado.

Em qualquer Server Function, certifique-se de validar se o usuário logado tem permissão para executar essa ação.

Under Construction

Para evitar o envio de dados sensíveis de uma Server Function, existem APIs experimentais de taint para impedir que valores e objetos exclusivos sejam passados para o código do cliente.

Veja experimental_taintUniqueValue e experimental_taintObjectReference.

Argumentos e valores de retorno serializáveis

Como o código do cliente chama a Server Function pela rede, quaisquer argumentos passados precisarão ser serializáveis.

Aqui estão os tipos suportados para os argumentos da Server Function:

Notavelmente, estes não são suportados:

  • Elementos React ou JSX
  • Funções, incluindo funções de componente ou qualquer outra função que não seja uma Server Function
  • Classes
  • Objetos que são instâncias de qualquer classe (além dos built-ins mencionados) ou objetos com um protótipo nulo
  • Símbolos não registrados globalmente, ex. Symbol('meu novo símbolo')
  • Eventos de manipuladores de eventos

Os valores de retorno serializáveis suportados são os mesmos que os props serializáveis para um Client Component de limite.

Uso

Server Functions em formulários

O caso de uso mais comum das Server Functions será chamar funções que mutam dados. No navegador, o elemento de formulário HTML é a abordagem tradicional para um usuário enviar uma mutação. Com React Server Components, o React introduz suporte de primeira classe para Server Functions como Actions em formulários.

Aqui está um formulário que permite a um usuário solicitar um nome de usuário.

// App.js

async function requestUsername(formData) {
'use server';
const username = formData.get('username');
// ...
}

export default function App() {
return (
<form action={requestUsername}>
<input type="text" name="username" />
<button type="submit">Request</button>
</form>
);
}

Neste exemplo, requestUsername é uma Server Function passada para um <form>. Quando um usuário envia este formulário, há uma requisição de rede para a função do servidor requestUsername. Ao chamar uma Server Function em um formulário, o React fornecerá o FormData do formulário como o primeiro argumento para a Server Function.

Ao passar uma Server Function para o formulário action, o React pode aprimorar progressivamente o formulário. Isso significa que formulários podem ser enviados antes que o bundle JavaScript seja carregado.

Manipulando valores de retorno em formulários

No formulário de solicitação de nome de usuário, pode haver a chance de um nome de usuário não estar disponível. requestUsername deve nos dizer se falha ou não.

Para atualizar a UI com base no resultado de uma Server Function ao mesmo tempo em que suporta o aprimoramento progressivo, use useActionState.

// requestUsername.js
'use server';

export default async function requestUsername(formData) {
const username = formData.get('username');
if (canRequest(username)) {
// ...
return 'successful';
}
return 'failed';
}
// UsernameForm.js
'use client';

import { useActionState } from 'react';
import requestUsername from './requestUsername';

function UsernameForm() {
const [state, action] = useActionState(requestUsername, null, 'n/a');

return (
<>
<form action={action}>
<input type="text" name="username" />
<button type="submit">Request</button>
</form>
<p>Última solicitação de envio retornou: {state}</p>
</>
);
}

Observe que, como a maioria dos Hooks, useActionState só pode ser chamado em código do cliente.

Chamando uma Server Function fora de <form>

As Server Functions são expostas como endpoints do servidor e podem ser chamadas em qualquer lugar no código do cliente.

Ao usar uma Server Function fora de um formulário, chame a Server Function em uma Transition, que permite que você exiba um indicador de carregamento, mostre atualizações de estado otimistas e lide com erros inesperados. Os formulários automaticamente encapsularão Server Functions em transitions.

import incrementLike from './actions';
import { useState, useTransition } from 'react';

function LikeButton() {
const [isPending, startTransition] = useTransition();
const [likeCount, setLikeCount] = useState(0);

const onClick = () => {
startTransition(async () => {
const currentCount = await incrementLike();
setLikeCount(currentCount);
});
};

return (
<>
<p>Total de curtidas: {likeCount}</p>
<button onClick={onClick} disabled={isPending}>Curtir</button>;
</>
);
}
// actions.js
'use server';

let likeCount = 0;
export default async function incrementLike() {
likeCount++;
return likeCount;
}

Para ler um valor de retorno da Server Function, você precisará fazer await na promise retornada.