stackbystep

React Hook Form:数字で始まるnameはNG

テクノロジー#React#TypeScript#プログラミング
公開 2026.10.17

この記事は3分で読めます

こんにちは。今日も記事をご覧いただきありがとうございます。

React Hook Form で、ライブラリを更新したらフォームのバリデーションエラーが急に表示されなくなりました。

原因は name を数字で始めていたことでした。備忘録として残しておきます。

起きたこと

設問ごとに入力欄を並べるフォームで、name に設問の番号をそのまま使っていました。

<Controller
  name={`${i}.value`}   // 数字で始まる name
  control={control}
  render={({ field }) => <input {...field} />}
/>

これまでは問題なく動いていましたが、@hookform/resolvers を v5.9.0 から v5.9.1 に上げたところ、エラーメッセージが入力欄に表示されなくなりました。

原因

そもそも数字で始まる name は使えない

公式ドキュメントの register のルールに、数字で始まる名前は使えないと書かれています。最近変わったルールではなく、v7(2021年)からあるものです。

React Hook Form は name を「.」区切りのパスとして扱い、数字だけの部分は配列の番号と解釈します。

そのため 0.value は、意図していた answers[0].value ではなく、ルート直下の "0" というキーを指してしまいます。

useForm<FormValues> で型を付けていれば、本来は型エラーで気づけるケースです。

それでも今まで動いていた理由

v5.9.1 で、エラーのパスを整える escapeBrackets という関数が修正されました(Issue #875)。

  • v5.9.0:「[」と「]」をただ消す → [0].value は 0.value になる
  • v5.9.1:[数字] を .数字 に変えてから消す → [0].value は .0.value になる

v5.9.0 では、変換後のパスが数字で始まる name と偶然一致していたため、エラーが表示されていました。

修正によって一致しなくなり、表示されなくなったというわけです。

対処法

数字で始まらないパスにします。今回は配列で持つ形にしました。

type FormValues = {
  answers: { id: number; value: string }[];
};

const { control } = useForm<FormValues>({
  defaultValues: {
    answers: questions.map((q) => ({ id: q.id, value: "" })),
  },
});

{questions.map((q, i) => (
  <Controller
    key={q.id}
    name={`answers.${i}.value`}
    control={control}
    render={({ field }) => <input {...field} />}
  />
))}

ポイントは、ID を値として持たせて、パスの番号には「何番目か」を使うことです。

answers.${q.id}.value のように ID を番号にすると、ID が 100 のとき長さ101の配列ができてしまうので注意が必要です。

配列にしなくても、q_1 のように先頭に文字を付けるだけでも解決します。

参考

記事を最後まで読んでいただきありがとうございました。また次の記事でお会いしましょう。

関連記事