Yup - Бібліотека для валідації \ перевірка введених користувачем

Валідація - це перевірка введених користувачем значень на відповідність деяким критеріям. Валідація на фронтенді - це передусім захист від неправильно введених значень перед їх відправленням на сервер.

npm install yup

const FeedbackSchema = Yup.object().shape({
username: Yup.string().min(2, "Too Short!").max(50, "Too Long!").required("Required")
});

const FeedbackSchema = Yup.object().shape({
username: Yup.string().min(2, "Too Short!").max(50, "Too Long!").required("Required"),
email: Yup.string().email("Must be a valid email!").required("Required"),
message: Yup.string().min(3, "Too short").max(256, "Too long").required("Required"),
level: Yup.string().oneOf(["good", "neutral", "bad"]).required("Required")
});
const initialValues = {
username: "",
email: "",
message: "",
level: "good"
};
const FeedbackForm = () => {
const nameFieldId = useId();
const emailFieldId = useId();
const msgFieldId = useId();
const levelFieldId = useId();
const handleSubmit = (values, actions) => {
console.log(values);
actions.resetForm();
};
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={FeedbackSchema}
>
<Form>
<label htmlFor={nameFieldId}>Username</label>
<Field type="text" name="username" id={nameFieldId} />
<label htmlFor={emailFieldId}>Email</label>
<Field type="email" name="email" id={emailFieldId} />
<label htmlFor={msgFieldId}>Message</label>
<Field as="textarea" name="message" id={msgFieldId} rows="5" />
<label htmlFor={levelFieldId}>Service satisfaction level</label>
<Field as="select" name="level" id={levelFieldId}>
<option value="good">Good</option>
<option value="neutral">Neutral</option>
<option value="bad">Bad</option>
</Field>
<button type="submit">Submit</button>
</Form>
</Formik>
);
};

Помилки валідації

Для того щоб відобразити користувачу помилки валідації, використовується компонент ErrorMessage.

import { ErrorMessage } from "formik";

Додамо його до розмітки форми поруч із кожним полем, наприклад, створимо таку групу.

Значення атрибута name компонентів ErrorMessage та Field повинно співпадати. Це потрібно для того, щоб ErrorMessage виводиво повідомлення про помилку валідації для пов'язаного поля.

За замовчуванням ErrorMessage відображає текст без тега, це не зручно, оскільки текст неможливо стилізувати. Проп as вказує, в якому тезі рендерити текст помилки.

<div>
<label htmlFor={nameFieldId}>Username</label>
<Field type="text" name="username" id={nameFieldId} />
<ErrorMessage name="username" as="span" />
</div>

Додамо виведення помилок валідації для всіх полів форми фідбеку. На цьому все, форма готова, розмітка набрана, поля валідуються, користувачеві виводяться повідомлення про помилки валідації, при відправці форми маємо об'єкт значень всіх її полів.

import { Formik, Form, Field, ErrorMessage } from "formik";
import { useId } from "react";
import * as Yup from "yup";
const FeedbackSchema = Yup.object().shape({
username: Yup.string().min(2, "Too Short!").max(50, "Too Long!").required("Required"),
email: Yup.string().email("Must be a valid email!").required("Required"),
message: Yup.string().min(3, "Too short").max(256, "Too long").required("Required"),
level: Yup.string().oneOf(["good", "neutral", "bad"]).required("Required"),
});
const initialValues = {
username: "",
email: "",
message: "",
level: "good",
};
const FeedbackForm = () => {
const nameFieldId = useId();
const emailFieldId = useId();
const msgFieldId = useId();
const levelFieldId = useId();
const handleSubmit = (values, actions) => {
console.log(values);
actions.resetForm();
};
return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={FeedbackSchema}
>
<Form>
<div>
<label htmlFor={nameFieldId}>Username</label>
<Field type="text" name="username" id={nameFieldId} />
<ErrorMessage name="username" as="span" />
</div>
<div>
<label htmlFor={emailFieldId}>Email</label>
<Field type="email" name="email" id={emailFieldId} />
<ErrorMessage name="email" as="span" />
</div>
<div>
<label htmlFor={msgFieldId}>Message</label>
<Field as="textarea" name="message" id={msgFieldId} rows="5" />
<ErrorMessage name="message" as="span" />
</div>
<div>
<label htmlFor={levelFieldId}>Service satisfaction level</label>
<Field as="select" name="level" id={levelFieldId}>
<option value="good">Good</option>
<option value="neutral">Neutral</option>
<option value="bad">Bad</option>
</Field>
<ErrorMessage name="level" as="span" />
</div>
<button type="submit">Submit</button>
</Form>
</Formik>
);
};