Manage Forms in React Like Pro
Tags: react, javascript, beginners, programming
Published: 2022-12-30 13:02:56

Hi, as a developer we always need to handle the forms and when we talk about the forms we also need to deal with the field validations, show the error messages, Mange the submitting status

If we start to write all these conditions from the scratch in the code we need to take a lot of state in your component for example let's take an example of login form requirements

The requirements are as below

1. We need to bind the form values
2. We need validation on the form if the email field is empty we have to show the “please enter email” error and if the email is incorrect we have to show the “please enter the correct email” error and for the password field it must be greater then 6 characters validation
3. When the form is submitting, we need to show the spinner in the button


Let us think about the logic for the above requirement

You must be thinking about the below logic

- Take one submitting state which stores the submitting status
- Take two states' email and password for storing email and password
- Take two more states for storing errors for email and password both
- And also to show the correct validation error you will make one function checkValidation which checks the validation and set the errors accordingly

States:

```
const [email, setEmail] = useState("");
  const [password, setPassWord] = useState("");
  const [emailError, setEmailError] = useState("");
  const [passwordError, setPassWordError] = useState("");
  const [isSubmitting, setISSubmitting] = useState(false);
```

Validation logic:

```
  const validateForm = () => {
    if (email) {
      const isCorrectEmail = false; // regex logic let take false as example
      if (!isCorrectEmail) {
        setEmailError("plase enter email");
      }
    } else {
      setEmailError("plase enter email");
    }
    if (password) {
      if (password.length < 6) {
        setPassWordError("password must be of min 6 characters");
      }
    } else {
      setPassWordError("plese enter password");
    }

    if (!emailError && !passwordError) {
      // submit from logic goes here
    }
  };
```

UI: 

```
 <div className="App">
      <div style={{ display: "flex", flexDirection: "column" }}>
        <input placeholder="email" onChange={(e) => setEmail(e.target.value)} />
        {emailError && <span>{emailError}</span>}
        <input
          placeholder="password"
          onChange={(e) => setPassWord(e.target.value)}
        />
        {passwordError && <span>{passwordError}</span>}
        <button
          onClick={() => {
            validateForm();
          }}
        >
          {isSubmitting ? "Spinner" : "Submit"}
        </button>
      </div>
    </div>

```
as you can see for just keeping track of two fields values and validation we have to write a lot of the boilerplate code. here is the formik that comes to the rescue.

**What is Formik?**

Formik is a form management library that helps us manage the form state without pain, formik can help you to bind the input fields, keep track of the form submitting status, manage from submissions count, and manage validation, for validation we will integrate Yup with the fromik.

Enough talk right :)

Let's install the dependencies and write some code

formik : “yarn add formik”
Yup : “yarn add yup”

you can also use any other library rather than yup but it is the most used formik so I am taking the example of that

formik provide the useFormik hooks that provide all the form helpers functions and the form values and error status.

Lets import dependencies:

```
import { useFormik } from "formik";
import * as Yup from "yup";
```

let setup useFormik Hooks:


```
  const formik = useFormik({
    initialValues: {
      email: "",
      password: ""
    },
    validationSchema: Yup.object({
      email: Yup.string()
        .required("email is requied field")
        .email("plese enter correct email"),
      password: Yup.string()
        .required("password is required")
        .min(6, "password must be of 6 characters")
    }),
    onSubmit: (values) => {
      onFormSubmit(values);
    }
```
  });


let's go though all the properties one by one, the initalValues store the initial values of the form, validationSchema defines the validation for the fields, if you don’t need validation for any field you can skip that in the validation schema object

in the formik use get a lot of variables and helper functions

```
 const { values, errors, submitForm, isSubmitting, handleChange } = formik;
```

values stores the from values in JSON type, errors also stores any errors in the JSON type, submitForm submit the forms and when we call this it will call onSubmit function written inside the useFormik hook, isSubmitting returns boolean whether the form is submitting or not, handleChange is the from helper.

Keep in mind that if we call the submitForm function and if there are any errors the form will not get submitted, when we call this first the form gets validated and if there are any errors formik adds them in the errors JSON.

let's bind all these to our form


```
 <div className="App">
      <div style={{ display: "flex", flexDirection: "column" }}>
        <input
          placeholder="email"
          name="email"
          onChange={handleChange}
          value={values.email}
        />
        {errors.email && <span>{errors.email}</span>}
        <input
          value={values.password}
          name="password"
          placeholder="password"
          onChange={handleChange}
        />
        {errors.password && <span>{errors.password}</span>}
        <button
          onClick={() => {
            submitForm();
          }}
        >
          {isSubmitting ? "Spinner" : "Submit"}
        </button>
      </div>
```


in the input, you can see I have passed handleChange helper to the input field, handleChange automatically bind the values with formik state but make sure you are also passing the name props with the field value specified in the initalvalues

you can get the form values in the values variable and errors in the errors one

final Output:

{% embed https://codesandbox.io/embed/relaxed-carson-gqir47?fontsize=14&hidenavigation=1&theme=dark %}


Hope you liked the Blog, if you like to read about React, Typescript, and Node stuff, You can follow me