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?

【備忘録】ReactHookForm+ChakraUIで編集モーダルを作る

Posted at

やりたいこと

編集ボタン押下時、編集用モーダルを展開、更新出来ること。

実装

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>
  </>

詰まっていたところ

  1. <input value={record.id} type="hidden" />としていたけどid要素が渡せていなかった。<input value={record.id} type="hidden" {...register("id")}/>でReactHookFormのregisterにidを設定できる。

  2. ReactHookFormの機能を使い、以下の方法でdefaultValuesに初期値を設定できる。

useForm<Record>({
  defaultValues: {
    title: record?.title || "",
    time: record?.time || "",
  },
1
0
0

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?