useActionState
是一個 Hook,允許您根據表單動作的結果更新狀態。
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
參考
useActionState(action, initialState, permalink?)
在組件的頂層呼叫 useActionState
來創建在 調用表單動作時 更新的組件狀態。您傳遞給 useActionState
一個現有的表單動作函式以及初始狀態,它會返回一個您在表單中使用的新的動作,以及最新的表單狀態和動作是否仍在處理中。最新的表單狀態也會傳遞給您提供的函式。
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>
)
}
表單狀態是上次提交表單時動作返回的值。如果表單尚未提交,則它是您傳遞的初始狀態。
如果與伺服器函式一起使用,useActionState
允許在完成水合之前顯示提交表單的伺服器響應。
參數
fn
:提交表單或按下按鈕時要呼叫的函式。當呼叫該函式時,它將接收表單的前一個狀態(最初是您傳遞的initialState
,隨後是它先前的返回值)作為其初始參數,後跟表單動作通常接收的參數。initialState
:您希望狀態最初的值。它可以是任何可序列化的值。第一次調用動作後,將忽略此參數。- 選用
permalink
:包含此表單修改的唯一頁面 URL 的字串。用於具有動態內容(例如:feed)的頁面,並與漸進增強一起使用:如果fn
是一個 伺服器函式 且在 JavaScript 捆綁包載入之前提交了表單,瀏覽器將導航到指定的 permalink URL,而不是當前頁面的 URL。確保在目標頁面上呈現相同的表單組件(包括相同的動作fn
和permalink
),以便 React 知道如何傳遞狀態。一旦表單被水合,此參數將不起作用。
回傳值
useActionState
返回一個包含以下值的陣列
- 目前的狀態。在第一次渲染期間,它將與您傳遞的
initialState
相符。調用動作後,它將與動作返回的值相符。 - 您可以將一個新的動作作為
action
prop 傳遞給您的form
元件,或者作為formAction
prop 傳遞給表單內任何的button
元件。 isPending
旗標會告訴您是否有正在處理中的 Transition(轉換)。
注意事項
- 當與支援 React 伺服器元件的框架一起使用時,
useActionState
允許您在客戶端執行 JavaScript 之前使表單具有互動性。如果不使用伺服器元件,它等同於元件的局部狀態。 - 傳遞給
useActionState
的函式會接收一個額外的參數,即先前的或初始的狀態,作為它的第一個參數。這使得它的簽名與直接用作表單動作而不使用useActionState
時不同。
用法
使用表單動作返回的資訊
在元件的最上層呼叫 useActionState
來存取上次提交表單時動作的返回值。
import { useActionState } from 'react';
import { action } from './actions.js';
function MyComponent() {
const [state, formAction] = useActionState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}
useActionState
會返回一個包含以下項目的陣列
- 表單的目前狀態,初始設定為您提供的初始狀態,在表單提交後,將設定為您提供的動作的返回值。
- 一個新的動作,您將其作為
action
prop 傳遞給<form>
。 - 一個pending 狀態,您可以在動作處理時使用它。
當提交表單時,您提供的動作函式將被呼叫。它的返回值將成為表單新的目前狀態。
您提供的動作也會收到一個新的第一個參數,即表單的目前狀態。第一次提交表單時,這將是您提供的初始狀態,而在後續提交中,它將是上次呼叫動作時的返回值。其餘的參數與未使用 useActionState
時相同。
function action(currentState, formData) {
// ...
return 'next state';
}
範例 1之 2: 顯示表單錯誤
要顯示伺服器函式返回的訊息,例如錯誤訊息或toast,請將動作包裝在對 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" /> </> ) }