前提・実現したいこと
現在React(Next.js)を使って、日付の入力フォームを作成しています。
その際に、react-hook-formを使っていますが、material-uiのDatePickerにて入力した値の処理がうまくいきません。
バリデーションにはyupを用いています。
入力される日付としては、nullが許容されるので
nullか正しい日付の場合のみ、onSubmit関数内でAPIを叩く形にする必要があります。
問題点
nullを許容するため、yup.date().nullable()としていますが、フォームで何も入れず登録ボタンを押すと、エラーとなります。
また、正しくない日付(例えば1だけ)を入力した場合にもバリデーションが通り、onSubmit関数が実行されています。
これを所望の「正しい日付かnullのみ許容」とするにはどうすれば良いでしょうか?
該当のソースコード
TypeScript
1/**@jsxImportSource @emotion/react */ 2import { yupResolver } from '@hookform/resolvers/yup/dist/yup'; 3import React, { useState } from 'react'; 4import { TextField, Button } from '@mui/material'; 5import { SubmitHandler, useForm } from 'react-hook-form'; 6import * as yup from 'yup'; 7import { DatePicker } from '@mui/lab'; 8import AdapterDateFns from '@mui/lab/AdapterDateFns'; 9import LocalizationProvider from '@mui/lab/LocalizationProvider'; 10import ja from 'date-fns/locale/ja'; 11import { setDate } from 'date-fns'; 12 13interface SampleFormInput { 14 start_date: string; 15} 16 17// バリデーション 18const schema = yup.object({ 19 start_date: yup.date().nullable().typeError('正しい日付を入力してください'), 20}); 21 22const Test = () => { 23 const { 24 register, 25 handleSubmit, 26 formState: { errors }, 27 } = useForm<SampleFormInput>({ 28 resolver: yupResolver(schema), 29 }); 30 31 const onSubmit: SubmitHandler<SampleFormInput> = async (data) => { 32 // APIを叩いて登録 33 }; 34 35 const [formStartDate, setFormStartDate] = useState(''); 36 return ( 37 <> 38 <LocalizationProvider dateAdapter={AdapterDateFns} locale={ja}> 39 <DatePicker 40 label="日付" 41 mask="____-__-__" 42 inputFormat="yyyy-MM-dd" 43 value={formStartDate} 44 onChange={(newValue) => { 45 setFormStartDate(newValue); 46 }} 47 renderInput={(params) => ( 48 <> 49 <TextField 50 {...params} 51 {...register('start_date')} 52 error={'start_date' in errors} 53 helperText={errors.start_date?.message} 54 variant="standard" 55 /> 56 </> 57 )} 58 /> 59 </LocalizationProvider> 60 <Button onClick={handleSubmit(onSubmit)}>登録</Button> 61 </> 62 ); 63}; 64 65export default React.memo(Test);
あなたの回答
tips
プレビュー