1
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?

【RHF】【Chakra】VitestからSelectフォームに設定した値がformDataに含まれない

Posted at

はじめに

react-hook-formとChakra V3でselectフォームを作成したところ、vitestのテストでselectフォーム(マルチセレクト)に設定した値が、submitした後のformDataに伝わらない事象が発生しました。

問題

selectフォームを含むtsx(一部抜粋)
<Field.Label htmlFor="skills">好きな技術</Field.Label>
<Controller
  control={control}
  name="skills"
  render={({ field, formState }) => (
    <Select.Root
      id="skills"
      multiple
      onValueChange={({ value }) => field.onChange(value)}
      onInteractOutside={() => field.onBlur()}
      variant={"outline"}
      collection={skillsOptions}
      invalid={!!formState.errors.skills}
    >
      <Select.HiddenSelect data-testid="skills-select" />
      <Select.Control>
        <Select.Trigger>
          <Select.ValueText placeholder="技術を選択してください" />
        </Select.Trigger>
        <Select.IndicatorGroup>
          <Select.Indicator />
        </Select.IndicatorGroup>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content>
            {skillsOptions.items.map((skillItem) => (
              <Select.Item
                item={skillItem}
                key={skillItem.value}
              >
                {skillItem.label}
                <Select.ItemIndicator />
              </Select.Item>
            ))}
          </Select.Content>
        </Select.Positioner>
      </Portal>
    </Select.Root>
  )}
/>

上記selectフォームのvalueに1と2を指定しfireEventのchangeイベントを発火させた後、送信ボタンをしたのですが、formDataのskillsがundefindのままになりました。

sample.spec.tsx
const fieldSkill = await screen.findByTextId("skills-select");
fireEvent.change(fieldSkill,{target:{value:[1,2]}}

解決方法

<Select.HiddenSelect data-testid="skills-select" />の指定をやめて、byRole="combobox"からoptionをちょこちょこクリックするように変更しました。

test("全項目入力して登録ボタンを押すと/に遷移する", async () => {
    Element.prototype.scrollTo = vi.fn();

    const fieldEnglishWord = await screen.findByLabelText("好きな英単語");
    const fieldUserName = await screen.findByLabelText("お名前");
    const fieldDescription = await screen.findByLabelText("自己紹介");
    const fieldSkill = await screen.findByRole("combobox");
    const fieldGithubId = await screen.findByLabelText("GitHub ID");
    const fieldQiitaId = await screen.findByLabelText("Qiita ID");
    const fieldXId = await screen.findByLabelText("X ID");
    const btnRegister = await screen.findByRole("button", { name: "登録" });

    await user.type(fieldEnglishWord, "butter2");
    await user.type(fieldUserName, "butter");
    await user.type(fieldDescription, "butter");
    await user.type(fieldGithubId, "butter");
    await user.type(fieldQiitaId, "butter");
    await user.type(fieldXId, "butter");

    await user.click(fieldSkill);
    await waitFor(() => {
      expect(fieldSkill).toHaveAttribute("aria-expanded", "true");
    });

    const options = screen.queryAllByRole("option");

    if (options) {
      await user.click(options[0]);
      await user.click(options[1]);
    }
    await user.click(btnRegister);
  });

おわりに

UIライブラリは便利ですが他のライブラリと併用した時や、想定外の挙動をした際に少し戸惑いますね..!

JISOUのメンバー募集中!

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!
▼▼▼
https://projisou.jp

1
0
1

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
1
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?