😸
Formikを使ったYupバリデーションで、最大文字数を可変させたい!
はじめに
氏名とメモなどの長い入力になりそうなものを編集するための共通モーダルみたいなもので、編集対象のものによって最大値のバリデーション値を変えたいことってありますよね?(氏名は10文字まででメモは100文字までなど)
今回はそんな時どうやって長さを変化させればいいのかを調べました。
結論
いきなり結論です。
方法としてはとても単純で、FormikのvalidationSchemaにYup.objectを返す関数を渡してあげてその関数の引数で最大値をもらう形で可変にできます。
FormikのvalidationSchemaの型を見に行くと下記のようになっています。
そのため関数で渡しても問題ないということになります!
/**
* A Yup Schema or a function that returns a Yup schema
*/
validationSchema?: any | (() => any);
実装例
validationSchema.ts
import * as Yup from "yup";
export const validationSchema = ({ maxLength }: { maxLength: number }) =>
Yup.object({
value: Yup.string().max(maxLength, `文字の最大値は${maxLength}です。`),
});
Form.tsx
import React from 'react';
import { Formik } from 'formik';
import { validationSchema } from './validation';
export const SignupForm: React.FC = () => {
return (
<Formik
initialValues={{ value: '' }}
validationSchema={() => validationSchema({maxLength: 16})} // 編集対象のものによって長さを変える
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{formik => (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="value">value</label>
<input
id="value"
type="text"
{...formik.getFieldProps('value')}
/>
{formik.touched.value && formik.errors.value ? (
<div>{formik.errors.value}</div>
) : null}
<button type="submit">Submit</button>
</form>
)}
</Formik>
);
};
終わりに
これでvalidationSchemaを使いまわすことができるため、同じようなパターンで長さだけ変わっているYup.Objectを沢山複製しなくてもすみますね!
Discussion