はじめに
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