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?

【備忘録】動的に追加されたinputタグをReact Hook FormのuseFieldArrayで管理する

Posted at

はじめに

動的に追加されたinputタグへの入力内容を RHF で管理する方法について記した備忘録です。

元の実装例

1.ボタンがクリックされた回数をstateで保持
2.registerの引数にstateの値を渡すことで、RHF側のキー が被らないようにする

export function InputProductLink() {
  const [clickCount, setClickCount] = useState(0);

  return (
    <div className="space-y-2">
      <p className="font-bold text-xl">作品関連リンク</p>
      {Array.from({ length: clickCount }, (_, index) => (
        <InputField
          type="url"
          placeholder="入力されたURLのドメインによってアイコンが決定されます。"
          registerName={`productlink${index}`}
          key={index}
        />
      ))}

      <div className="flex space-x-2">
        <LinkAddButton setClickCount={setClickCount} />
        <SaveDBButton />
      </div>
    </div>
  );
}

・このようなキーになります

image.png

元の実装例でキーを配列にする方法

registerの引数を下記のように指定することで、配列の要素とすることが出来ます。

registerName={`productlink.${index}`}

useFieldArrayを使った実装例

1.useFormContextからcontrolを取り出して、useFieldArrayに渡す。
2.useFieldArrayの引数 nameuseFormdefaultValueのキーregisterの引数 を渡す。
3.ループにはfieldsを使う。
4.要素の追加にはuseFieldArrayからappendを取り出して使う。
5.要素の削除にはuseFieldArrayからremoveを取り出して使う。

・親コンポーネント側の実装

export function InputProductLink() {
  const { control } = useFormContext();
  const { fields, append, remove } = useFieldArray({
    name: "productLinks",
    control,
  });

  return (
    <div className="space-y-2">
      <p className="font-bold text-xl">作品関連リンク</p>
      {fields.map((field, index) => (
        <InputField
          key={field.id}
          type="url"
          placeholder="入力されたURLのドメインによってアイコンが決定されます。"
          registerName={`productLinks.${index}`}
        />
      ))}

      <div className="flex space-x-2">
        <LinkAddButton append={append} />
        <SaveDBButton />
      </div>
    </div>
  );
}

・子コンポーネント側の実装

export function LinkAddButton({ append }: linkAddButtonProps) {
  return (
    <button
      onClick={() => append("")}
      className="flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition duration-300"
      type="button"
    >
      <span className="text-xl mr-2">+</span>
      <span>追加する</span>
    </button>
  );
}

さいごに

学習させていただいた記事のリンクです。

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?