0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Hook FormのuseFieldArrayで現在の値を取得する方法

Posted at

概要

React Hook Form の useFieldArray は、フォームのフィールドを動的に追加・削除できる便利なフックです。

「現在の入力値を取得したい」と思ったときに、fields を参照しても意図した値が得られないことがあります。

本記事では 「useFieldArray の現在の値を正しく取得する方法」 を解説します!✨

1. useFieldArray で現在の値を取得するには?

useFieldArrayfields は、フォームの入力データそのものではなく、レンダリングのための情報を提供するものです。

したがって、以下のように fields を直接使っても、リアルタイムな入力値は取得できません。

console.log(fields); // 現在の入力値は取得できない!

✅ 正しく取得する方法 → watch を使う

useForm には watch という関数があり、フォームの現在の状態をリアルタイムで取得できます。

つまり、watch("items") を使うことで、useFieldArray の現在の値を簡単に取得できます!

2. watch を使った実装例

以下のコードでは、動的にフィールドを追加・削除しながら、リアルタイムで現在の入力値を表示しています。

import { useForm, useFieldArray } from "react-hook-form";

type FormValues = {
  items: { name: string }[];
};

export default function MyForm() {
  const { control, register, handleSubmit, watch } = useForm<FormValues>({
    defaultValues: { items: [{ name: "" }] }
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: "items"
  });

  // ✅ 現在の値をリアルタイムで取得
  const watchedItems = watch("items");

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      {fields.map((field, index) => (
        <div key={field.id}>
          <input {...register(`items.${index}.name`)} />
          <button type="button" onClick={() => remove(index)}>削除</button>
        </div>
      ))}
      <button type="button" onClick={() => append({ name: "" })}>追加</button>

      {/* ✅ 現在の値を表示 */}
      <pre>現在の値: {JSON.stringify(watchedItems, null, 2)}</pre>

      <button type="submit">送信</button>
    </form>
  );
}

3. watch を使うメリット

watch("items") を使うことで、以下のようなメリットがあります。

✅ リアルタイムに値を取得できる

  • useFieldArrayfields では取得できない「現在の入力データ」がすぐに取れる!

✅ 余計なステート管理が不要

  • useState を使わなくても watch だけで値を取得できるため、シンプルな実装が可能!

✅ フォーム全体の変更を即座にキャッチできる

  • watch は他のフィールドの変更を監視できるので、フォーム全体のデータをリアルタイムで扱いたいときにも便利!

4. key の設定について(補足)

React Hook Form の公式ドキュメントには、以下のような注意書きがあります。

The field.id (and not index) must be added as the component key to prevent re-renders breaking the fields:

(key には index ではなく field.id を使うこと。そうしないと、再レンダリングでフィールドの内容が壊れる可能性がある)

実際に、以下のように indexkey に使うと、削除時に入力内容がずれることがあります。

// ❌ index を key に使うのは NG!
{fields.map((field, index) => (
  <div key={index}>
    <input {...register(`items.${index}.name`)} />
  </div>
))}

そこで、key には field.id を使うのが推奨されます。

// ✅ 正しい key の設定方法
{fields.map((field, index) => (
  <div key={field.id}>
    <input {...register(`items.${index}.name`)} />
  </div>
))}

まとめ

useFieldArrayfields では現在の値を取得できない
✔ リアルタイムな入力値を取得するには watch("items") を使う
watch を使うと、余計なステート管理なしでフォームの値を取得できる
key には field.id を使い、再レンダリング時の不具合を防ぐ

useFieldArray で現在の値を取得する際に悩んでいる方は、ぜひ watch を活用してみてください!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?