Yup小技集
numberもしくはnullかをチェックしたい場合
yup
.number()
.nullable()
.transform((value, originalValue) =>
String(originalValue).trim() === '' ? null : value
)
これでチェックのところは解決したが、String型で出力されてしまう。
本来は上記の処理で組み込みたかったが一旦スキップ。
暫定的にsubmitする直前にNumber()
で数値型にする
特定のいずれかにチェックが入っていることを確認する
const validationSchema = Yup.object().shape({
online: Yup.boolean(),
offline: Yup.boolean(),
hybrid: Yup.boolean(),
// カスタムバリデーションで少なくとも1つが true か確認
}).test('at-least-one-true', 'オンライン、オフライン、またはハイブリッドのいずれかを選択してください', function (values) {
const { online, offline, hybrid } = values;
return online || offline || hybrid;
});
test
を使用することで実現可能
数字を指定し、その数だけ値が入力されているか確認
examNum: Yup.number().required('試験回数を入力してください').min(1, '1以上の数を入力してください'),
examDate: Yup.array()
.of(Yup.date().required('開催予定日を入力してください'))
.test('check-examNum', 'すべての試験予定日を入力してください', function (value) {
const { examNum } = this.parent;
return value && value.length >= examNum && value.slice(0, examNum).every((date) => date !== null);
}),
examNum
examNumでは1以上の数値が入っているかを確認する
number()
で数値であること、required
で必須項目として定義する
examDate
examDateはそれぞれの日付が入力されているかを確認する。
配列の中身を定義する方法は上記のarray().of(yup.number())
もしくはarray(yup.number());
の2種類がある。 公式ドキュメント-array
その後、test
を使用して作成した入力欄に記入されているかを確認する
test()の第一引数はテスト名、第二引数が失敗した際に表示するエラーメッセージ
this.parent
は、examDate が属しているオブジェクト全体を参照する。parent経由で他の値を参照することができる
function
の引数にはexamDateの値が格納される
value && value.length >= examNum
でexamDate 配列の長さが examNum 以上であることを確認。
value.slice(0, examNum).every((date) => date !== null)
のvalue.slice(0, examNum)
は、examDate 配列の最初から examNum 個までの要素を抽出
.every((date) => date !== null)
は、抽出した要素がすべて null ではないことを確認します。つまり、必要な試験日すべてが入力されていることを検証 (everyについて)
AutoCompleteのエラー対応
The value provided to Autocomplete is invalid.
None of the options match with `{"id":1,"name":"Instructor 1"}`.
You can use the `isOptionEqualToValue` prop to customize the equality test. Error Component Stack
上記のエラーに対してはエラーメッセージ通りisOptionEqualToValue
を追加することで解消
<Autocomplete
// 省略
isOptionEqualToValue={(option: Instructor, value: Instructor) => option.id === value.id}
// 省略
/>```
動的なバリデーション
配列で回して作成したインプットフォームのバリデーションルール
const attendanceSchemas = attendance.reduce((acc, item) => {
const methodField = `method${item.method}`;
const attendanceField = `${methodField}Attendance`;
return {
...acc,
[attendanceField]: Yup.number()
.typeError('人数は数値で入力してください')
.nullable()
.transform((value, originalValue) => (String(originalValue).trim() === '' ? null : value))
.when(methodField, {
is: true,
then: (schema) =>
schema
.required('人数は必須です')
.min(1, '1以上の数を入力してください')
.max(9999, '9999以下の数を入力してください'),
}),
};
}, {});
const validationSchema = Yup.object()
.shape(
{
// 省略
...attendanceSchemas,
},
[],
)