useActionState Hook ใหม่ใน React 19 ที่ช่วยให้ submit form ง่ายขึ้นเยอะ (มั้ง)

Web Development

useActionState Hook ใหม่ใน React 19 ที่ช่วยให้ submit form ง่ายขึ้นเยอะ (มั้ง)

7 วันที่ผ่านมา

2 min read

useActionState เป็น Hook ตัวใหม่ใน React 19 ที่ช่วยให้การจัดการ state ที่เกี่ยวข้องกับฟอร์มเป็นเรื่องง่ายขึ้นมาก โดยมันช่วยลดความซับซ้อนของการจัดการฟังก์ชัน onSubmit ในฟอร์มต่าง ๆ โดยตรง

ใน React 18 เราอาจเคยเห็น Hook ที่ชื่อ useFormState ซึ่งเป็นเวอร์ชันทดลอง แต่ใน React 19 ชื่อนั้นถูกเปลี่ยนมาเป็น useActionState พร้อมฟีเจอร์ที่สมบูรณ์

What is useActionState

useActionState คือ Hook ที่ออกแบบมาให้ช่วยจัด state ของ Form หลังจากการดำเนินการ (action) เสร็จสมบูรณ์

“useActionState is a Hook that allows you to update state based on the result of a form action.”

หรือพูดง่าย ๆ มันคือเครื่องมือที่ช่วยจัดการ state โดยพิจารณาจากผลลัพธ์ของ action ที่ถูกส่งจากฟอร์ม

โดยหน้าตาของ hook เวลาเราเรียกใช้งาน จะเป็นแบบนี้

const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);

Parameters

โดยสิ่งที่ต้องส่งให้ hook คือ function และ initial state ส่วน permalink คือ optional

  • fn คือ function ที่ใช้ในการอัพเดท state
  • initialState คือค่าเริ่มต้นของ state
  • permalink คือ URL ใช้สำหรับเก็บ state ระหว่างหน้าต่าง ๆ (ไม่บังคับใส่)

Return Value

โดยสิ่งที่ได้กลับมาหลังจาก เรียกใช้งาน ก็จะมี

  • state คือ ค่าปัจจุบันที่ return จาก useActionState
  • formAction คือ function ที่ต้องผูกกับ action ของฟอร์ม
  • isPending คือ สถานะของการส่ง form อยู่ในระหว่างรอการตอบรับ ใช้สำหรับทำ loading ตอน submit form ได้

ตัวอย่างการใช้งาน

1. Counter Form

ฟอร์มตัวอย่างที่เพิ่มค่าตัวเลขในทุกครั้งที่กดปุ่ม Submit

import { useActionState } from "react";
 
async function increment(previousState, formData) {
  return previousState + 1;
}
 
function CounterForm() {
  const [state, formAction] = useActionState(increment, 0);
 
  return (
    <form action={formAction}>
      <p>Counter: {state}</p>
      <button type="submit">Increment</button>
    </form>
  );
}

2. แสดง Error Message จากการ Submit

ตัวอย่างนี้แสดงการส่งข้อมูลไปยัง action เพื่อตรวจสอบว่าการเพิ่มสินค้าลงในตะกร้าสำเร็จหรือไม่

mport { useActionState } from "react";
import { addToCart } from "./actions.js";
 
function AddToCartForm({ itemID, itemTitle }) {
  const [message, formAction] = useActionState(addToCart, null);
 
  return (
    <form action={formAction}>
      <h2>{itemTitle}</h2>
      <input type="hidden" name="itemID" value={itemID} />
      <button type="submit">Add to Cart</button>
      {message && <p className="error">{message}</p>}
    </form>
  );
}

function addToCart

//action.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.";
  }
}

3. Preserving Form State Across Pages

กรณีที่ต้องการให้ state ของฟอร์มถูกบันทึกไว้ระหว่างการเปลี่ยนหน้า เช่น ในตัวอย่างนี้คือ ฟอร์ม Feedback

import { useActionState } from "react";
import { submitFeedback } from "./actions.js";
 
function FeedbackForm() {
  const [feedback, formAction] = useActionState(
    submitFeedback,
    "",
    "/feedback",
  );
 
  return (
    <form action={formAction}>
      <textarea name="feedback" placeholder="Your feedback" />
      <button type="submit">Submit</button>
      <p>{feedback}</p>
    </form>
  );
}

ประโยชน์ของใช้ useActionState

  • ลด Boilerplate Code เพราะไม่ต้องเขียนฟังก์ชัน onSubmit หรือ useState ซ้ำ ๆ
  • สะดวกในการจัดการ Loading State เพราะมีตัวแปร isPending ช่วยจัดการสถานะการโหลดได้ง่าย
  • สามารถแชร์ state ระหว่างหน้าได้ โดยการใช้ permalink เพื่อคงค่าของฟอร์มไว้ในหลายหน้า

Reference

Tags:

React

บทความอื่นๆ

ดูความที่คุณอาจจะสนใจ ได้จากบทความข้างใต้นี้