ReactJS - useFormState() 鉤子



useFormState 是 React 網站的有用工具。當我們想要根據填寫表單時發生的情況來更新網頁上的內容時,我們會使用它。例如,我們可能想要在點選表單中的按鈕時增加一個數字。

語法

useFormState(func, initialState)

引數

func − 當表單提交或按下按鈕時,將呼叫函式 fn。當我們呼叫函式時,它將接收表單的先前狀態(首先是我們傳遞的 initialState,然後是其先前的返回值)作為其第一個引數,然後是表單操作通常接收的引數。

initialState − 開始時的狀態值。可以使用任何可序列化的值。在第一次呼叫操作後,將忽略此引數。

返回值

useFormState 生成一個僅包含兩個值的陣列:

  • 當前狀態。它將與我們在第一次渲染時傳遞的 initialState 匹配。當呼叫操作時,它將與操作返回的值匹配。

  • 一個新的操作,我們可以將其作為 action prop 或 formAction prop 傳送到我們的表單元件,傳送到表單內的任何按鈕元件。

示例

示例 - 計數器增減應用

在元件的頂層,使用 useFormState 設定在執行表單操作時更新的元件狀態。我們向 useFormState 提供現有的表單操作函式和初始狀態,它將返回一個新的操作和最新的表單狀態。最新的表單狀態也傳送到我們指定的函式。

在這個新的例子中,我們將使用 useFormState 建立一個基本的計數器,當按下“減”按鈕時遞減。

import { useFormState } from "react-dom";

async function increment(previousState, formData) {
   return previousState + 1;
}

async function decrement(previousState, formData) {
   return previousState - 1;
}

export default function App({}) {
   const [state, incrementAction] = useFormState(increment, 0);
   const [state2, decrementAction] = useFormState(decrement, 0);
   
   return (
      <div>
         <form>
            <p>Counter: {state}</p>
            <button formAction={incrementAction}>Increment</button>
            <button formAction={decrementAction}>Decrement</button>
         </form>
      </div>
   );
}

輸出

counter2

示例

在這個例子中,我們將建立一個允許使用者提交產品反饋的應用程式。為了管理反饋表單並根據使用者的輸入顯示訊息,我們將使用 useFormState。程式碼如下:

actions.js

"use server";

export async function submitFeedback(prevState, queryData) {
   const feedback = queryData.get("feedback");
   if (feedback) {
      return "Thanks for your feedback!";
   } else {
      return "Please provide your feedback before submitting.";
   }
}

App.js

import { useFormState } from "react-dom";
import { submitFeedback } from "./actions.js";

function FeedbackForm() {
   const [message, formAction] = useFormState(submitFeedback, null);
   
   return (
      <form action={formAction}>
         <h2>Product Feedback</h2>
         <label>
            Your Feedback:
            <textarea name="feedback" />
         </label>
         <button type="submit">Submit Feedback</button>
         {message}
      </form>
   );
}

export default function App() {
   return (
      <div>
         <FeedbackForm />
      </div>
   );
}

輸出

product feedback

在上面的例子中,我們有一個 FeedbackForm 元件,允許使用者提供產品反饋。它根據使用者是否使用 actions.js 中的 submitFeedback 操作提供了反饋來顯示訊息。App 元件渲染反饋表單。根據需要,我們可以建立 FeedbackForm 元件的多個例項。

示例

所以讓我們再看一個使用 useFormState 函式的例子。在這個應用程式中,我們將建立一個簡單的線上商店,我們可以在其中將商品新增到我們的購物車。在主元件“AddToCartForm”中,我們有兩個屬性:itemID 和 itemTitle,分別表示商品的唯一 ID 和標題。在 AddToCartForm 內,有一個表單,其中包含一個隱藏的 item ID 輸入和一個按鈕,用於將商品新增到購物車。該表單使用 react-dom 庫中的 useFormState 鉤子。因此,該應用程式在 actions.js 檔案中使用簡單的伺服器端設定。

import { useState } from "react";
import { useFormState } from "react-dom";
import { addToCart } from "./actions.js";

function AddToCartForm({itemID, itemTitle}) {
   const [message, formAction] = useFormState(addToCart, null);
   return (
      <form action={formAction}>
         <h2>{itemTitle}</h2>
         <input type="hidden" name="itemID" value={itemID} />
         <button type="submit">Add to Cart</button>
         {message}
      </form>
   );
}

export default function App() {
   return (
      <>
         <AddToCartForm itemID="1" itemTitle="Dynamic Programming: Models and App" />
         <AddToCartForm itemID="2" itemTitle="Soft Computing Techniques for Engineering Optimization" />
      </>
   )
}

actions.js

"use server";

export async function addToCart(prevState, queryData) {
   const itemID = queryData.get('itemID');
   if (itemID === "1") {
      return "Added to cart";
   } else {
      return "Couldn't add to cart: the item is sold out.";
   }
}

輸出

dynamic programming

總的來說,這個應用程式展示了在 React 中新增商品到購物車的基本表單處理機制。

限制

  • 當與支援 React 伺服器元件的框架一起使用時,UseFormState 允許我們在客戶端執行 JavaScript 之前使表單具有互動性。在不使用伺服器元件的情況下,它類似於元件區域性狀態。

  • 作為其第一個引數,提供給 useFormState 的函式接收一個額外的引數,即先前或起始狀態。這改變了如果沒有使用 useFormState 直接用作表單操作時的簽名。

總結

useFormState 函式幫助我們設定和管理元件內表單的行為。我們向它提供指定的動作函式和初始狀態,它將返回當前表單狀態和一個新的動作,該動作可用於啟動表單更新。

reactjs_reference_api.htm
廣告
© . All rights reserved.