react-hook-formとReact Datepickerを組み合わせる

公開日時

Next.jsアプリケーションでフォームを扱う必要があったので、React Hook Formを利用した。

また、カレンダーから日時選択ができるようにしたかったのでReact Datepickerと組み合わせることにした。

hook-form
  • components/DatePicker.tsx

Hook FormのControllerのドキュメントを参考にDatePicker用のコンポーネントを作成。

import 'react-datepicker/dist/react-datepicker.css'

import React from 'react'
import ReactDatePicker from 'react-datepicker'
import { Control, Controller, Path } from 'react-hook-form'

type Props<T> = {
  label: string
  name: Path<T>
  error?: string
  control: Control<T>
  timeIntervals?: number
}

export const DatePicker = <T,>({
  label,
  name,
  control,
  error,
  timeIntervals = 15,
}: Props<T>) => {
  return (
    <>
      <label htmlFor={name}>
        {label}
      </label>
      <div>
        <Controller
          control={control}
          name={name}
          render={({ field: { onChange, value } }) => (
            <ReactDatePicker
              dateFormat="yyyy-MM-dd HH:mm"
              showTimeSelect
              timeIntervals={timeIntervals}
              onChange={onChange}
              selected={value as Date}
            />
          )}
        />
      </div>
      <span>{error}</span>
    </>
  )
}

ジェネリクスの型引数を指定する際に <T> がコンポーネントとして認識されてしまいハマった。

const DatePicker = <T>(...) ではなく const DatePicker = <T,>(...) と指定する必要があった。

  • pages/edit.tsx

あとは useForm を使用しているページでDatePickerコンポーネントを呼び出せばReact Datepickerによる日付選択が可能になる。

import { DatePicker } from '@/components/DatePicker'

type FormValues = {
  datetime: string;
} 

const EditPage = () => {
  const {
    control,
    formState: { errors },
  } = useForm<FormValues>()

  return (
    <DatePicker
      label="datetime"
      name="datetime"
      control={control}
      error={errors.datetime?.message}
    />
  )
}

export default EditPage

参考


Related #next.js

Next.jsのPreview Mode時はAnalyticsを無効化する

cookieの__next_preview_dataキーで判定

PWAアプリにクイックショートカットを追加する

manifest.jsonにshortcutsを追加

Next.js 10.0.1 + React 17.0の環境でTypeError: Object(...) is not a functionエラーが発生

一つ前のReact 16.13に下げてみたらエラーが解消された

Next.jsプロジェクトにTypescriptを導入する

チュートリアルが充実してる

Next.js + typescriptでpathsのエイリアスがModule not foundになる

next.config.jsに追記する必要があった