useActionState
useActionState é um Hook que permite que você atualize o estado com base no resultado de uma action de formulário.
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);Referência
useActionState(action, initialState, permalink?)
Chame useActionState no nível raiz do seu componente para criar um estado de componente que é atualizado quando uma action de formulário é invocada. Você passa para o useActionState uma função de action de formulário existente, bem como um estado inicial, e ele retorna uma nova action que você usa no seu formulário, juntamente com o estado atual do formulário e se a Action ainda está pendente. O estado atual do formulário também é passado para a função que você forneceu.
import { useActionState } from "react";
async function increment(previousState, formData) {
return previousState + 1;
}
function StatefulForm({}) {
const [state, formAction] = useActionState(increment, 0);
return (
<form>
{state}
<button formAction={formAction}>Increment</button>
</form>
)
}O estado do formulário é o valor retornado pela action quando o formulário foi enviado pela última vez. Se o formulário ainda não foi enviado, é o estado inicial que você passa.
Se usado com uma Server Function, useActionState permite que a resposta do servidor do envio do formulário seja exibida mesmo antes da conclusão da hidratação.
Parâmetros
fn: A função a ser chamada quando o formulário é enviado ou o botão pressionado. Quando a função é chamada, ela receberá o estado anterior do formulário (inicialmente oinitialStateque você passa, subsequentemente seu valor de retorno anterior) como seu primeiro argumento, seguido pelos argumentos que uma ação de formulário normalmente recebe.initialState: O valor que você deseja que o estado seja inicialmente. Pode ser qualquer valor serializável. Este argumento é ignorado depois que a action é invocada pela primeira vez.- opcional
permalink: Umastringque contém a URL exclusiva da página que este formulário modifica. Para uso em páginas com conteúdo dinâmico (por exemplo: feeds) em conjunto com aprimoramento progressivo: sefné uma server function e o formulário é enviado antes que o bundle JavaScript seja carregado, o navegador navegará para a URL da permalink especificada, em vez da URL da página atual. Certifique-se de que o mesmo componente de formulário seja renderizado na página de destino (incluindo a mesmaaction fnepermalink) para que React saiba como passar o state. Depois que o formulário for hidratado, este parâmetro não terá efeito.
Retorna
useActionState retorna um array com os seguintes valores:
- O estado atual. Durante a primeira renderização, ele corresponderá ao
initialStateque você passou. Depois que a action for invocada, ele corresponderá ao valor retornado pela action. - Uma nova action que você pode passar como a prop
actionpara seu componenteformou a propformActionpara qualquer componentebuttondentro do formulário. A action também pode ser chamada manualmente dentro destartTransition. - A flag
isPendingque informa se existe uma Transition pendente.
Ressalvas
- Quando usado com um framework que oferece suporte a React Server Components,
useActionStatepermite que você torne os formulários interativos antes que o JavaScript tenha sido executado no cliente. Quando usado sem Server Components, é equivalente ao estado local do componente. - A função passada para
useActionStaterecebe um argumento extra, o estado anterior ou inicial, como seu primeiro argumento. Isso torna sua assinatura diferente do que se fosse usado diretamente como uma action de formulário sem usaruseActionState.
Uso
Usando informações retornadas por uma action de formulário
Chame useActionState no nível raiz do seu componente para acessar o valor de retorno de uma action da última vez que um formulário foi enviado.
import { useActionState } from 'react';
import { action } from './actions.js';
function MyComponent() {
const [state, formAction] = useActionState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}useActionState retorna um array com os seguintes itens:
- O estado atual do formulário, que é inicialmente definido como o estado inicial que você forneceu e, após o formulário ser enviado, é definido como o valor de retorno da action que você forneceu.
- Uma nova action que você passa para o
<form>como sua propactionou chama manualmente dentro destartTransition. - Um estado pendente que você pode utilizar enquanto sua action está processando.
Quando o formulário é enviado, a função action que você forneceu será chamada. Seu valor de retorno se tornará o novo estado atual do formulário.
A action que você fornece também receberá um novo primeiro argumento, ou seja, o estado atual do formulário. Na primeira vez que o formulário for enviado, este será o estado inicial que você forneceu, enquanto com envios subsequentes, será o valor de retorno da última vez que a action foi chamada. O restante dos argumentos são os mesmos de se useActionState não tivesse sido usado.
function action(currentState, formData) {
// ...
return 'next state';
}Example 1 of 2: Exibir erros de formulário
Para exibir mensagens como uma mensagem de erro ou toast que é retornado por uma Server Function, envolva a action em uma chamada para useActionState.
import { useActionState, useState } from "react"; import { addToCart } from "./actions.js"; function AddToCartForm({itemID, itemTitle}) { const [message, formAction, isPending] = useActionState(addToCart, null); return ( <form action={formAction}> <h2>{itemTitle}</h2> <input type="hidden" name="itemID" value={itemID} /> <button type="submit">Add to Cart</button> {isPending ? "Loading..." : message} </form> ); } export default function App() { return ( <> <AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" /> <AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" /> </> ) }
Solução de problemas
Minha action não consegue mais ler os dados do formulário enviado
Quando você envolve uma action com useActionState, ela recebe um argumento extra como seu primeiro argumento. Os dados do formulário enviado são, portanto, seu segundo argumento em vez de seu primeiro, como seria normalmente. O novo primeiro argumento que é adicionado é o estado atual do formulário.
function action(currentState, formData) {
// ...
}