همراه با نسخه React 19 پشتیبانی از Form Actionها، یک کامپایلر جدید و همچنین هوک‌های جدید برای مدیریت فرم مانند useFormState نیز منتشر می‌شوند. در این مقاله قصد داریم تا با مفاهیم اصلی هوک useFormState، نحوه استفاده از این هوک و تعامل آن با Form Actionها آشنا شویم.

Form Actionها

ابتدا قصد داریم تا نحوه استفاده از form actionها را بررسی کنیم. برای شروع کار به دو چیز نیاز داریم: یک فرم برای ارسال به form action، و server action که داده‌ها را از فرم دریافت می‌کند، آن‌ها را پردازش کرده و نتیجه را return می‌نماید.

کار خود را از سمت سرور شروع می‌کنیم. برای ایجاد یک server action، ماژول دیگری را می‌سازیم، به عنوان مثال formPostAction.ts و در آن فایل یک server action مانند مثال زیر تعریف می‌کنیم:

"use server";

type FormState = {
  message: string;
}

export async function onFormPostAction(prevState: FormState, data: FormData) {
   // Process the data
   return {
      message: "Form data processed";
   }
}

تابع server action  onFormPostAction باید به عنوان یک تابع async تعریف شود. همچنین باید دستور "use server" را در خط اول تابع بنویسیم، یا اینکه مانند مثالی که داریم دستور "use server" را در بالای فایل ماژول قرار دهیم. حالت دوم به این معنی است که تمام توابع موجود در این فایل، توابع سرور هستند.

برای استفاده از هوک useFormState بر روی کلاینت، action ما باید دارای یک signature خاص باشد. به این صورت که state قبلی به عنوان آرگومان اول و داده‌های فرم به عنوان آرگومان دوم در نظر گرفته می‌شوند. شکل state فرم به ما بستگی دارد؛ در این مثالی که داریم، state فقط یک message در خود دارد. نکته‌ای که باید به آن توجه داشته باشیم این است که هم state قبلی و هم فرم return شده از تابع post action باید از یک تایپ باشند.

اکنون قصد داریم تا این موضوع را بر روی کلاینت امتحان کنیم.

استفاده از هوک useFormState در کلاینت

برای استفاده از form action در کلاینت، باید آن تابع action را از formPostAction.ts import کرده و از react-dom به تابع useFormState بفرستیم، به عنوان مثال:

"use client";
import { useFormState } from "react-dom";

import { onFormPostAction } from "./formPostAction.ts";

export default function MyForm() {
  const [state, action] = useFormState(onFormPostAction, {
    message: "",
  });
   // ...
}

با توجه به دستور "use client"; که در بالای فایل می‌بینیم، این فایل یک کلاینت کامپوننت است. زیرا، ما برای این که بتوانیم از هوک useFormState استفاده کنیم به آن نیاز داریم.

سپس در بدنه کامپوننت، useFormState را فراخوانی می‌کنیم و تابع server action و state اولیه را به آن اختصاص می‌دهیم. آبجکت state اولیه باید با تایپ FormState در formPostAction.ts مطابقت داشته باشد.

درنهایت، خروجی یک تاپل با state فعلی و یک تابع action است. در رندر اولیه، آن مقدار state با state اولیه مطابقت دارد. اما پس از ارسال فرم، state همان چیزی خواهد بود که از سرور return شده است.

تابع action همان چیزی است که به تگ form ارسال می‌کنیم. به این صورت که:

export default function MyForm() {
  const [state, action] = useFormState(...);
  const [first, setFirst] = useState("");
   
  return (
    <form action={action}>
       <input
          type="text" name="first"
          value={first} onChange={(e) => setFirst(e.target.value)}
       />
       <button type="submit">Submit</button>
    </form>
  );
}

اکنون یک تگ form اضافه کرده‌ایم که دارای ویژگی action می‌باشد که با تابع action reuturn شده از useFormState تعریف شده است. همچنین یک فیلد input برای نام دارد که از state استاندارد هوک useState استفاده می‌کند و همینطور یک دکمه submit نیز دارا می‌باشد.

در اولین رندر یک فیلد خالی برای نام داریم که می‌توانیم آن را پر کنیم. با زدن دکمه ارسال، آن داده‌ها را به عنوان داده‌های فرم به server action ارسال می‌کنیم و پیام بازگشتی را به عنوان state دریافت می‌کنیم.

می‌توانیم آن state را به سادگی و با استفاده از JSX به نمایش بگذاریم:

return (
   <form action={action}>
     <div>{state.message}</div>
     ...
   </form>
 );

در ابتدا این قطعه کد یک div خالی از state اولیه را نشان می‌دهد. سپس، پس از یک پست، هر آنچه را که سرور ارسال می‌کند، به کاربر نمایش خواهیم داد.

باید این نکته را به خاطر داشته باشیم که می‌توانیم هر داده‌ای که می‌خواهیم را ارسال کنیم، و همچنین می‌توانیم از آن state بازگشتی در هر نقطه از کامپوننت، به صورت دلخواه استفاده نماییم.

مزیت استفاده از هوک useFormState

در حال حاضر استفاده از هوک useFormState یک مکانیسم بسیار نرم برای مدیریت فرم‌ها به حساب می‌آید، اما اگر به درستی از این ویژگی استفاده کنیم، یک مزیت بسیار مهم در آن وجود دارد. ما می‌توانیم بدون فعال کردن جاوااسکریپت کار خود را انجام دهیم. یعنی اگر جاوااسکریپت را در مرورگر خود غیرفعال کرده و دوباره کد را امتحان کنیم مشاهده می‌کنیم که برنامه ما بدون هیچ مشکلی کار خواهد کرد.

جمع‌بندی

ما در این مقاله سعی کردیم تا یکی از ویژگی‌های جدیدی که به نسخه ۱۹ React اضافه شده است را باهم بررسی کنیم. Form actionها و هوک useFormState یکی از راه‌هایی هستند که React از آن استفاده می‌کند تا سرعت بالای خود را حفظ کرده و حتی بهبود ببخشد و از سایر فریم‌ورک‌های موجود پیشی بگیرد.