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 oinitialState
que 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
: Umastring
que 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 fn
epermalink
) 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
initialState
que 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
action
para seu componenteform
ou a propformAction
para qualquer componentebutton
dentro do formulário. A action também pode ser chamada manualmente dentro destartTransition
. - A flag
isPending
que informa se existe uma Transition pendente.
Ressalvas
- Quando usado com um framework que oferece suporte a React Server Components,
useActionState
permite 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
useActionState
recebe 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 propaction
ou 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) {
// ...
}