やりたいこと
編集ボタン押下時、編集用モーダルを展開、更新出来ること。
実装
App.tsx
{/* ChakraUIのモーダル機能を利用する */}
const { isOpen, onOpen, onClose } = useDisclosure();
/**
* 編集ボタン押下時、編集モーダルを展開する
*/
const openEdit = (id: string, title: string, time: string) => {
setRecord({
id: id,
title: title,
time: time
});
setIsEditMode(true); // モーダル展開時に登録と編集を判定する用
onOpen();
}
{ !loading && records ? (
<div className="record-container">
{records.map((item) => {
return (
<div key={item.id} className="record-item">
<p data-testid="item">{item.title}:{item.time}</p>
<button onClick={() => openEdit(item.id, item.title, item.time)} data-testid={`edit-button-${item.id}`}>編集</button>
</div>
)
})}
recordModal.tsx
// モーダルのコンポーネント
const { register, handleSubmit, formState: {errors}} = useForm<Record>({
defaultValues: {
title: record?.title || "",
time: record?.time || "",
},
});
/**
* フォームから値を抽出する
*/
const handleUpdate = (data: Record) => {
onUpdate(data); // App.tsxに値を返す
}
return (
<>
<ModalOverlay />
<ModalContent className="modal-content">
<ModalBody data-testid="confirm-modal">
{ isEdit ? (
<>
<h3>編集</h3>
<form>
{/* idも渡したい*/}
<input value={record.id} type="hidden" {...register("id")}/>
<div>
学習内容<Input
type="text"
data-testid="edit-title"
aria-invalid={errors.title ? "true" : "false"}
placeholder='タイトルを入力してください'
{...register("title", { required: true })}
/>
</div>
<div>
学習時間<Input
type="number"
data-testid="edit-time"
aria-invalid={errors.time ? "true" : "false"}
placeholder='時間を入力してください'
{...register("time", { required: true })}
/>
</div>
</form>
</>
) : (
<>
{/* 登録の場合の処理 */}
</>
)}
</ModalBody>
<ModalFooter>
<Button colorScheme='blue' mr={3} onClick={onClose}>
Close
</Button>
{ isEdit ? (
{/* handleSubmitはReactHookFormの機能 */}
<Button variant='ghost' onClick={handleSubmit(handleUpdate)} data-testid="confirm-ok">更新</Button>
) : (
{/* 登録ボタン */}
)
}
</ModalFooter>
</ModalContent>
</>
詰まっていたところ
-
<input value={record.id} type="hidden" />
としていたけどid要素が渡せていなかった。<input value={record.id} type="hidden" {...register("id")}/>
でReactHookFormのregisterにidを設定できる。 -
ReactHookFormの機能を使い、以下の方法でdefaultValuesに初期値を設定できる。
useForm<Record>({
defaultValues: {
title: record?.title || "",
time: record?.time || "",
},