Jak vytvořit jednoduchý formulář s ověřením pomocí yup a formiku (vhodné pro začátečníky)

Jen si představte tu frustraci, která může pocházet z vyplňování špatně ověřeného formuláře :( Pravděpodobně se odrazíte od stránky. Na povrchové úrovni se formuláře velmi jednoduše sestavují, ale pokud jde o jejich ověřování, může to být trochu výzva.

Zkoušel jsem sestavit formulář s validacemi před pár týdny a trochu jsem s tím bojoval. Když jsem nakonec našel svou cestu, uvědomil jsem si, že bude skvělé o tom napsat příspěvek, protože stejné výzvě může čelit mnohem více lidí.

Dnes vás seznámím s tím, jak jsem vytvořil formulář s těmito poli:

Jméno

Věk

E-mail

Heslo

Potvrdit heslo

**Tlačítko deaktivováno, dokud nebudou splněna všechna ověření

Tento příspěvek by byl rozdělen na 3 části

  1. Vytvoření formuláře
  2. Vytvoření ověření
  3. Kliknutím na tlačítko Odeslat by uživatelé měli přejít na uvítací stránku

První část

Začněme vytvořením formuláře v React

Vytvoření formuláře bez rozdělení polí formuláře na komponenty

import React from "react";

function Form() {
  return (
    <form>
      <div>
        <label htmlFor="name">Name</label>
        <input type="text" name="name" id="name" placeholder="Please Enter your name" />
      </div>
      <div>
        <label htmlFor="age">Age</label>
        <input type="number" name="age" id="age" placeholder="Please Enter your age" />
      </div>
      <div>
        <label htmlFor="email">Email</label>
        <input type="email" name="age" id="email" placeholder="Please Enter your email" />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          type="password"
          name="password"
          id="password"
          placeholder="Please Enter your password"
        />
      </div>
      <div>
        <label htmlFor="confirm-password">Confirm Password</label>
        <input
          type="password"
          name="confirm-password"
          id="confirm-password"
          placeholder="Please Confirm your password"
        />
      </div>
      <button>Submit</button>
    </form>
  );
}

export default Form;

Bude to vypadat takto

Chcete-li omezit opakování kódu, vytvořte komponentu pole formuláře, která jako rekvizity převezme:labelName, název, typ a zástupný symbol.

Komponenta pole formuláře by vypadala takto:

import React from "react";

function FormField({ name, label, ...rest }) {
  return (
    <div >
      <label htmlFor={name}>{label}</label>
      <input  id={name} name={name} {...rest} />
    </div>
  );
}

export default FormField;

Refaktoring naší Form Component by dal:

import React from "react";
import FormField from "./FormField";

function Form() {
  return (
    <form>
      <FormField
        label="Name"
        type="text"
        name="name"
        placeholder="Please Enter your name"
      />
      <FormField
        label="Age"
        type="number"
        name="age"
        placeholder="Please Enter your age"
      />
      <FormField
        label="Email"
        type="email"
        name="email"
        placeholder="Please Enter your email"
      />
      <FormField
        label="Password"
        type="password"
        name="password"
        placeholder="Please Enter your password"
      />
      <FormField
        label="Confirm Password"
        type="password"
        name="confirm-password"
        placeholder="Please Confirm your password"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

export default Form;

Část druhá

Ověření tohoto formuláře jsou uvedena níže:

  1. Jméno:Název nesmí mít méně než 3 znaky
  2. E-mail:musí to být platná e-mailová adresa
  3. Věk:Musí být alespoň 18 let a maximálně 60 let
  4. Heslo:Musí obsahovat alespoň jedno velké písmeno, jedno číslo, speciální znak a nesmí být kratší než 8 znaků
  5. Potvrdit heslo:Musí odpovídat poli pro heslo

Abychom mohli začít, museli bychom nainstalovat a importovat 2 knihovny do naší aplikace.

  1. Ano:Ano je nástroj pro tvorbu schémat JavaScriptu pro analýzu a ověřování hodnot.https://www.npmjs.com/package/yup
  2. Formik:Formik je knihovna, která vám pomáhá spravovat stav ve formulářích, zpracovávat ověřování, chybové zprávy a odesílání formulářů.https://jaredpalmer.com/formik/docs/overview

Dále bychom vytvořili počáteční hodnoty pro pole formuláře

const initialValues = {
  name: "",
  age: "",
  email: "",
  password: "",
  confirmPassword: ""
};

Poté vytvoříme objekt našeho ověřovacího schématu pomocí yup

const validationSchema = yup.object().shape({
  name: yup
    .string()
    .required("Name is a required field")
    .min(3, "Name must be at least 3 characters"),
  age: yup
    .number()
    .required("Please supply your age")
    .min(18, "You must be at least 18 years")
    .max(60, "You must be at most 60 years"),
  email: yup
    .string()
    .email()
    .required("Email is a required field"),
  password: yup
    .string()
    .required("Please enter your password")
    .matches(
      /^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/,
      "Password must contain at least 8 characters, one uppercase, one number and one special case character"
    ),
  confirmPassword: yup
    .string()
    .required("Please confirm your password")
    .when("password", {
      is: password => (password && password.length > 0 ? true : false),
      then: yup.string().oneOf([yup.ref("password")], "Password doesn't match")
    })
});

Sloučením všeho do podoby komponenty formuláře

import React from "react";
import { useFormik } from "formik";
import * as yup from "yup";
import FormField from "./FormField";


//setting the initial values
const initialValues = {
  name: "",
  age: "",
  email: "",
  password: "",
  confirmPassword: ""
};

//creating the validation schema
const validationSchema = yup.object().shape({
  name: yup
    .string()
    .required("A name is required")
    .min(2, "Name must be at least 2 characters"),
  age: yup
    .number()
    .required("Please supply your age")
    .min(18, "You must be at least 18 years")
    .max(60, "You must be at most 60 years"),
  email: yup
    .string()
    .email()
    .required("Email is a required field"),
  password: yup
    .string()
    .required("Please enter your password")
    .matches(
      /^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/,
      "Password must contain at least 8 characters, one uppercase, one number and one special case character"
    ),
  confirmPassword: yup
    .string()
    .required("Please confirm your password")
    .when("password", {
      is: password => (password && password.length > 0 ? true : false),
      then: yup.string().oneOf([yup.ref("password")], "Password doesn't match")
    })
});

function Form({ onSubmit }) {
  //using useFormik 
  const formik = useFormik({
    initialValues,
    validationSchema,
    onSubmit
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <FormField
        label="Name"
        type="text"
        name="name"
        placeholder="Please Enter your name"
      />
      <FormField
        label="Age"
        type="number"
        name="age"
        placeholder="Please Enter your age"
      />
      <FormField
        label="Email"
        type="email"
        name="email"
        placeholder="Please Enter your email"
      />
      <FormField
        label="Password"
        type="password"
        name="password"
        placeholder="Please Enter your password"
      />
      <FormField
        label="Confirm Password"
        type="password"
        name="confirm-password"
        placeholder="Please Confirm your password"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

export default Form;

** Všimněte si, že jsme prošli onSubmit callback do háku useFormik a také předal onSubmit={formik.handleSubmit} do formy.

V tuto chvíli je náš úkol téměř dokončen, potřebujeme pouze využít několik dalších rekvizit a zajistit, aby se chybové zprávy zobrazovaly

Budeme využívat getFieldProps.

  • getFieldProps je způsob, jak omezit standardní (opakující se) kód.
  • Vrátí pomocné metody jako onChange , onBlur , value , name .*
  • @viz Formik https://jaredpalmer.com/formik/docs/tutorial#getfieldprops
  const nameProps = formik.getFieldProps("name");
  const ageProps = formik.getFieldProps("age");
  const emailProps = formik.getFieldProps("email");
  const passwordProps = formik.getFieldProps('password');
  const confirmPasswordProps = formik.getFieldProps('confirmPassword');

Nakonec bychom museli zobrazit chybové zprávy, když ověření není splněno. Například pro pole názvu by bylo použití formik

{formik.touched.name && formik.errors.name ? (
        <div>{formik.errors.name}</div>
      ) : null}

Konečný kód pro tento formulář by byl

import React from "react";
import { useFormik } from "formik";
import * as yup from "yup";
import FormField from "./FormField";

//setting the initial values
const initialValues = {
  name: "",
  age: "",
  email: "",
  password: "",
  confirmPassword: ""
};

//creating the validation schema
const validationSchema = yup.object().shape({
  name: yup
    .string()
    .required("A name is required")
    .min(2, "Name must be at least 2 characters"),
  age: yup
    .number()
    .required("Please supply your age")
    .min(18, "You must be at least 18 years")
    .max(60, "You must be at most 60 years"),
  email: yup
    .string()
    .email()
    .required("Email is a required field"),
  password: yup
    .string()
    .required("Please enter your password")
    .matches(
      /^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/,
      "Password must contain at least 8 characters, one uppercase, one number and one special case character"
    ),
  confirmPassword: yup
    .string()
    .required("Please confirm your password")
    .when("password", {
      is: password => (password && password.length > 0 ? true : false),
      then: yup.string().oneOf([yup.ref("password")], "Password doesn't match")
    })
});

function Form({ onSubmit }) {
  //using useFormik
  const formik = useFormik({
    initialValues,
    validationSchema,
    onSubmit
  });

  //use formik.getFieldProps for input fields
  const nameProps = formik.getFieldProps("name");
  const ageProps = formik.getFieldProps("age");
  const emailProps = formik.getFieldProps("email");
  const passwordProps = formik.getFieldProps("password");
  const confirmPasswordProps = formik.getFieldProps("confirmPassword");

  /**
   * getFieldProps is a way to reduce boilerplate (repetitive) code.
   * It returns helper methods like `onChange`, `onBlur`, `value`, `name`.
   *
   * @see Formik https://jaredpalmer.com/formik/docs/tutorial#getfieldprops
   */
  return (
    <form onSubmit={formik.handleSubmit}>
      <FormField
        label="Name"
        type="text"
        placeholder="Please Enter your name"
        {...nameProps}
      />
      {formik.touched.name && formik.errors.name ? (
        <div>{formik.errors.name}</div>
      ) : null}
      <FormField
        label="Age"
        type="number"
        {...ageProps}
        placeholder="Please Enter your age"
      />
      {formik.touched.age && formik.errors.age ? (
        <div>{formik.errors.age}</div>
      ) : null}
      <FormField
        label="Email"
        type="email"
        placeholder="Please Enter your email"
        {...emailProps}
      />
      {formik.touched.email && formik.errors.email ? (
        <div>{formik.errors.email}</div>
      ) : null}
      <FormField
        label="Password"
        type="password"
        placeholder="Please Enter your password"
        {...passwordProps}
      />
      {formik.touched.password && formik.errors.password ? (
        <div>{formik.errors.password}</div>
      ) : null}
      <FormField
        label="Confirm Password"
        type="password"
        placeholder="Please Confirm your password"
        {...confirmPasswordProps}
      />
      {formik.touched.confirmPassword && formik.errors.confirmPassword ? (
        <div>{formik.errors.confirmPassword}</div>
      ) : null}
      <button type="submit" disabled={!(formik.isValid && formik.dirty)}>Submit</button>
    </form>
  );
}

export default Form;

Všimněte si, že k deaktivaci tlačítka, dokud nebudou splněna všechna ověření formuláře, jsem prošel pouze:disabled={!(formik.isValid && formik.dirty)} jako podpěra do tlačítka.

Část 3

Jako u každého formuláře chcete, aby uživatelé po kliknutí na tlačítko Odeslat přešli na jinou stránku. Ukážu vám, jak přesně to udělat.

(Pro případ, že byste potřebovali další vysvětlení ohledně směrování, v příštím příspěvku na blogu vás krok za krokem provedu, jak nastavit směrování v reakci).

Prozatím vše, co musíte udělat, je:

  1. Nainstalujte "react-router-dom"
  2. Vytvořte komponentu nebo stránku, kterou budou uživatelé zobrazovat po odeslání formuláře. V mém případě vytvořím uvítací stránku
import React from "react";

function Welcome() {
  return (
    <div>
      <h3>Hello and welcome</h3>
    </div>
  );
}

export default Welcome;

Do aplikace vložte toto:

import React from "react";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import Form from "./Form";
import Welcome from "./Welcome";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route
          exact
          path="/"
          render={props => (
            <Form
              onSubmit={value => {
                props.history.push("/welcome");
              }}
            />
          )}
        />
        <Route exact path="/welcome" component={Welcome} />
      </Switch>
    </Router>
  );
}

Gratulujeme, právě jste dokončili tento jednoduchý tutoriál.

Doufám, že to bylo opravdu užitečné, abyste pochopili, jak vytvořit formulář s validací od začátku pomocí yup a formiku.

Zanechte laskavě komentář, pokud to považujete za užitečné, a podívejte se na mé další příspěvky.