はじめに
開発中Checkboxがクリックできない症状が発生したため、こちらの解決方法を共有させていただきます。
次のように記述していました。
.Register.tsx
import { Box, Button, Card, CardBody, CardHeader, Checkbox, CheckboxGroup, FormLabel, Heading, Input, Radio, RadioGroup, Stack, Text, Textarea, useFormErrorStyles } from "@chakra-ui/react"
import { Controller, useForm } from "react-hook-form";
import { useSkills } from "../hooks/useSkills";
import { UserParams } from "../domain/users";
export const Register = () => {
const { register, handleSubmit, control, formState: { errors } } = useForm<UserParams>();
const { skillsData } = useSkills();
return (
<div>
<Box display="flex" justifyContent="center" alignItems="center" height="100vh" bg="#e4e4e7">
<Card pl={5} pr={5}>
<CardHeader textAlign="center">
<Heading size='lg'>新規名刺登録</Heading>
</CardHeader>
<Text ml={6} fontSize= "13px" as="span" color="#CC6666">* は必須項目です</Text>
<Stack>
<CardBody>
<Box textAlign="center">
<form onSubmit={handleSubmit((data) => {
console.log("dataの中身", data);
})}>
{/* ユーザーID */}
<FormLabel fontWeight={"bold"}>ユーザーID <Text as="span" color="#CC6666">*</Text></FormLabel>
<Input type="text" placeholder="ユーザーIDを入力してください" {...register("user_id", { required: true})} />
<Box textAlign="left">{errors.user_id && <Text as="span" fontSize="14px" color="red">入力必須です</Text>}</Box>
{/* 名前 */}
<FormLabel fontWeight={"bold"} mt={2}>名前 <Text as="span" color="#CC6666">*</Text></FormLabel>
<Input type="text" placeholder="名前を入力してください" {...register("name", { required: true})} />
<Box textAlign="left">{errors.name && <Text as="span" fontSize= "14px" color="red">入力必須です</Text>}</Box>
{/* 自己紹介 */}
<FormLabel fontWeight={"bold"} mt={2}>自己紹介 <Text as="span" color="#CC6666">*</Text></FormLabel>
<Textarea placeholder="自己紹介文を入力してください。HTMLタグも使えます" {...register("description", { required: true})} />
<Box textAlign="left">{errors.description && <Text as="span" fontSize= "14px" color="red">入力必須です</Text>}</Box>
{/* 好きな技術 */}
<FormLabel fontWeight={"bold"} mt={2}>好きな技術 <Text as="span" color="#CC6666">*</Text></FormLabel>
<Controller // controller使用しないと制御できない
name="skills" // どのフィールドを管理するか指定 フォーム送信時にここで指定した値がオブジェクトのキーとして扱われる
defaultValue={[]} // デフォルトの値
control={control} // usFormから取得したcontrolを渡している。これによりコンポーネントがフォームの状態管理に接続される
render={({ field }) => { // fieldという決まった名称のオブジェクト
return (
<CheckboxGroup value={field.value} >
{skillsData.map((skill) => (
<Checkbox ml={1} mr={1} key={skill.id} value={skill.id} required={true}>{skill.name}</Checkbox> // ← ここをクリックできません
))}
</CheckboxGroup>
);
}}
/>
{/* GitHub ID */}
<FormLabel mt={2}>GitHub ID</FormLabel>
<Input placeholder="IDを入力してください" {...register("github_id")} />
{/* Qiita ID */}
<FormLabel mt={2}>Qiita ID</FormLabel>
<Input placeholder="IDを入力してください" {...register("qiita_id")} />
{/* X ID */}
<FormLabel mt={2}>X ID</FormLabel>
<Input placeholder="IDを入力してください" {...register("x_id")} />
{/* 登録ボタン */}
<Button mt={3} colorScheme='teal' type="submit">登録</Button>
</form>
</Box>
</CardBody>
</Stack>
</Card>
</Box>
</div >
)
}
解決方法
ChecxboxGroupのonChangeに値を渡す。その値をCheckboxの値と同じにする。
chakra uiのGroupはデフォルトで値を文字列にすることから、数値に変換。
※ 文字列に統一しても挙動はするようでした
.Register.tsx
import { Box, Button, Card, CardBody, CardHeader, Checkbox, CheckboxGroup, FormLabel, Heading, Input, Radio, RadioGroup, Stack, Text, Textarea, useFormErrorStyles } from "@chakra-ui/react"
import { Controller, useForm } from "react-hook-form";
import { useSkills } from "../hooks/useSkills";
import { UserParams } from "../domain/users";
export const Register = () => {
const { register, handleSubmit, control, formState: { errors } } = useForm<UserParams>();
const { skillsData } = useSkills();
return (
<div>
<Box display="flex" justifyContent="center" alignItems="center" height="100vh" bg="#e4e4e7">
<Card pl={5} pr={5}>
<CardHeader textAlign="center">
<Heading size='lg'>新規名刺登録</Heading>
</CardHeader>
<Text ml={6} fontSize= "13px" as="span" color="#CC6666">* は必須項目です</Text>
<Stack>
<CardBody>
<Box textAlign="center">
<form onSubmit={handleSubmit((data) => {
console.log("dataの中身", data);
})}>
{/* ユーザーID */}
<FormLabel fontWeight={"bold"}>ユーザーID <Text as="span" color="#CC6666">*</Text></FormLabel>
<Input type="text" placeholder="ユーザーIDを入力してください" {...register("user_id", { required: true})} />
<Box textAlign="left">{errors.user_id && <Text as="span" fontSize="14px" color="red">入力必須です</Text>}</Box>
{/* 名前 */}
<FormLabel fontWeight={"bold"} mt={2}>名前 <Text as="span" color="#CC6666">*</Text></FormLabel>
<Input type="text" placeholder="名前を入力してください" {...register("name", { required: true})} />
<Box textAlign="left">{errors.name && <Text as="span" fontSize= "14px" color="red">入力必須です</Text>}</Box>
{/* 自己紹介 */}
<FormLabel fontWeight={"bold"} mt={2}>自己紹介 <Text as="span" color="#CC6666">*</Text></FormLabel>
<Textarea placeholder="自己紹介文を入力してください。HTMLタグも使えます" {...register("description", { required: true})} />
<Box textAlign="left">{errors.description && <Text as="span" fontSize= "14px" color="red">入力必須です</Text>}</Box>
{/* 好きな技術 */}
<FormLabel fontWeight={"bold"} mt={2}>好きな技術 <Text as="span" color="#CC6666">*</Text></FormLabel>
<Controller // controller使用しないと制御できない
name="skills" // どのフィールドを管理するか指定 フォーム送信時にここで指定した値がオブジェクトのキーとして扱われる
defaultValue={[]} // デフォルトの値
control={control} // usFormから取得したcontrolを渡している。これによりコンポーネントがフォームの状態管理に接続される
render={({ field }) => { // fieldという決まった名称のオブジェクト
return (
<CheckboxGroup value={field.value} onChange={(values) => field.onChange(values.map(Number))}> {/* Chakra uiのGroup Hook Formのデフォルトの値文字列から数値に変換が必要*/}
{skillsData.map((skill) => (
<Checkbox ml={1} mr={1} key={skill.id} value={skill.id} required={true}>{skill.name}</Checkbox>
))}
</CheckboxGroup>
);
}}
/>
{/* GitHub ID */}
<FormLabel mt={2}>GitHub ID</FormLabel>
<Input placeholder="IDを入力してください" {...register("github_id")} />
{/* Qiita ID */}
<FormLabel mt={2}>Qiita ID</FormLabel>
<Input placeholder="IDを入力してください" {...register("qiita_id")} />
{/* X ID */}
<FormLabel mt={2}>X ID</FormLabel>
<Input placeholder="IDを入力してください" {...register("x_id")} />
{/* 登録ボタン */}
<Button mt={3} colorScheme='teal' type="submit">登録</Button>
</form>
</Box>
</CardBody>
</Stack>
</Card>
</Box>
</div >
)
}
参考
おわりに
chakra UIのCheckboxGroupはデフォルトで文字列を返すことを学びました。