LoginSignup
0
0

はじめに

React19では、新たに<form action={非同期関数}>の形式で、フォームアクションが追加されました
これにより、フォームの送信時に非同期関数を直接呼び出せるようになり、よりシンプルなコードが書けるようになります
本記事では、この新機能の使い方とその利便性について詳しく解説します
また、この新機能useFormStatusというフォームの送信中の状態を取得するフックも追加されてより利便性が向上しました

formアクションの使用

以下の例では、フォーム送信時にhandleSubmit関数が非同期に呼び出されます

React19の実装例

import { useState } from 'react';
import { useFormStatus } from 'react-dom';

async function handleSubmit(formData) {
  const response = await fetch('/api/submit', {
    method: 'POST',
    body: formData
  });

  if (!response) {
    throw new Error('Network response was not ok');
  }
  
  return await response.json();
}

function MyForm() {
  const [status, setStatus] = useState(null);
  const { isPending } = useFormStatus();

  return (
    <form action={handleSubmit} >
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>
        {isPending ? 'Submitting...' : 'Submit'}
      </button>
      {status && <p>{status}</p>}
    </form>
  );
}

export default MyForm;

この実装の利点

  • 簡潔なコード
    • フォームのaction属性に非同期関数を直接指定することで、コードが簡潔になり、読みやすさが向上します
  • 非同期処理の簡素化
    • フォーム送信時に非同期処理を簡単に組み込むことができ、従来のイベントハンドラを使う方法よりも直感的です
  • 進行中状態の明示化
    • useFormStatusフックを使用することで、フォーム送信中の状態をisPendingプロパティとして取得し、ボタンの状態を動的に変更できます

Reat18以前の実装方法

React18以前では、フォームの送信イベントをキャッチし、その中で非同期処理を行なっていました

React18以前の実装例

import { useState } from 'react';

async function handleSubmit(event) {
  event.preventDefault();
  const formData = new FormData(event.target);
  const response = await fetch('/api/submit', {
    method: 'POST',
    body: formData,
  });

  if (!response.ok) {
    throw new Error('Network response was not ok');
  }

  const result = await response.json();

  return result;
}

function MyForm() {
  const [status, setStatus] = useState(null);
  const [isPending, setIsPending] = useState(false);

  const handleFormSubmit = async (event) => {
    event.preventDefault();
    setIsPending(true);

    try {
      const result = await handleSubmit(event);
      setStatus(`Success: ${result.message}`);
    } catch (error) {
      setStatus(`Error: ${error.message}`);
    } finally {
     setIsPending(false);
    }
};

  return (
    <form onSubmit={handleFormSubmit}>
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>
          {isPending ? 'Submitting... : 'Submit'}
      </button>
      {status && <p>{status}</p>}
    </form>
  );
}

React18以前では汎用的なuseStateを多用するのでどうしても分岐が多くなってしまいますね

まとめ

React19のformアクション機能により、フォームの非同期処理がより簡単かつ直感的に実装できるようになりました
この新機能とuseFormStatusフックを活用することで状態管理が簡潔で可読性の高いコードを書けるようになり、開発者の負担を軽減することができるようになるでしょう

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0