Using Chakra UI, React Hook Form, and Yup for React Form Validation.
Tags: react, yup, reacthookform, chakraui
Published: 2020-12-13 12:59:17

---
title: Using Chakra UI, React Hook Form, and Yup for React Form Validation.
published: true
description: Form validation is an integral component of most web applications. We will use react-hook-form and yup to validate forms in a react app built with Chakra UI
tags: react, yup, reacthookform, chakraui
//cover_image: https://direct_url_to_image.jpg
---
When building our react applications, we more often than not have to validate user generated content before we send it to our api endpoints for processing and storage. 

Recently, we started development on a product at my workplace. We decided to go with React. I insisted we use Chakra for our UI components. Partly because I am Nigerian and it absolutely gladdens my heart to see my compatriots doing great work and partly because [Chakra](https://chakra-ui.com/) is really good. For one, Chakra gives you accessibility by default. I cannot overemphasise how important that was for us.

One stumbling block with using Chakra was the lack of resources on the internet for when you inevitably run into trouble. This is understandable because it is still pretty young. This is my attempt to fill some of that gap.


## Validating a login form with react-hooks-form, and yup.
I am assuming the reader has some knowledge setting up react. If you do not, please visit the [react website](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app) for instructions on how to set up a react app.

Here is what we expect to achieve at the end of this:
![Animated login form](https://dev-to-uploads.s3.amazonaws.com/i/bolr2h2n28frtq0a47es.gif)

After creating a new project with React, we need to install Chakra, React Hook form, and Yup. For that we open our terminal, navigate to our project's folder.

- install chakra
```shell
npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion

# or

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
```

- install yup, react-hook-form, and @hookform/resolvers. We install @hookform/resolvers because react-hook-form supports multiple schema libraries besides yup.

```shell
npm i yup react-hook-form @hookform/resolvers

# or

yarn add yup react-hook-form @hookform/resolvers
```

- next we wrap our app with the Chakra provider so we can use Chakra components in our app. This we will do in our app's entry point, `index.tsx` in my case. 

```typescript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { ChakraProvider } from '@chakra-ui/react';

ReactDOM.render(
  <React.StrictMode>
    <ChakraProvider>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
  document.getElementById('root')
);
```

Now, we have our set up complete, let's now get down to building the login form.

- First, we import the Form components provided by Chakra. These components give us nice, accessible form components. I won't go into explaining what each do because I do not want this to become very long. Please visit the [Chakra documentation](https://chakra-ui.com/docs/getting-started) for more information on these components.
```typescript
import {
  FormControl,
  FormLabel,
  FormErrorMessage,
  FormHelperText,
  Input,
  Button
} from '@chakra-ui/react';
```

Then we import `yup`, `yupResolver`, and `useForm` to manage validation for our forms. Again, please visit [React Hook Form docs](https://react-hook-form.com/get-started) and [Yup docs](https://github.com/jquense/yup) for more information on these imports.
```typescript
import * as yup from 'yup';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
``` 

We create the form schema and the type definitions for our form inputs. The type definitions are for Typescript users.
```typescript
const schema = yup.object().shape({
  email: yup.string().email().required(),
  password: yup.string().min(8).required(),
});

type LoginFormInputs = {
  email: string;
  password: string;
};
```

Now, let's use all of these to create our login form. We will register our inputs into react hook form using `useForm`. The reason is clearly stated in the docs:
> One of the key concepts in React Hook Form is to register your uncontrolled component into the hook. This will make its value available for both the form validation and submission.

> Note: Each field is required to have a unique name as a key for the registration process.

`useForm` returns to us an `errors` object containing our validation errors [if any], a `handleSubmit` function that takes callback which is executed if validation is successful, and a `register` function we use to register our inputs. We set the `mode` to `onBlur` so our inputs are validated when the user leaves the input field
```typescript
const { register, handleSubmit, errors } = useForm<LoginFormInputs>({
    mode: 'onBlur',
    resolver: yupResolver(schema),
  });
```

Now, we register our inputs. We use `FormControl` because it:
>provides context such as isInvalid, isDisabled, and isRequired to form elements.

We use `errortext` to display the errors from our errors object, if any.
```typescript
<FormControl
        isInvalid={!!errors?.email}
        errortext={errors?.email?.message}
        p='4'
        isRequired
      >
        <FormLabel>Email</FormLabel>
        <Input type='email' name='email' placeholder='Email' ref={register} />
        <FormErrorMessage>{errors?.email?.message}</FormErrorMessage>
        <FormHelperText>
          We are obviously giving this straight to Facebook.
        </FormHelperText>
      </FormControl>
```

Here's what the full component looks like:
```typescript
import {
  FormControl,
  FormLabel,
  FormErrorMessage,
  FormHelperText,
  Input,
  Button
} from '@chakra-ui/react';
import * as yup from 'yup';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';

const schema = yup.object().shape({
  email: yup.string().email().required(),
  password: yup.string().min(8).required(),
});

type LoginFormInputs = {
  email: string;
  password: string;
};

export default function LoginForm() {
  const { register, handleSubmit, errors } = useForm<LoginFormInputs>({
    mode: 'onBlur',
    resolver: yupResolver(schema),
  });

  const onSubmit = (values: LoginFormInputs) => console.log(values);

  return (
    <form style={{ width: 350 }}>
      <FormControl
        isInvalid={!!errors?.email?.message}
        errortext={errors?.email?.message}
        p='4'
        isRequired
      >
        <FormLabel>Email</FormLabel>
        <Input type='email' name='email' placeholder='Email' ref={register} />
        <FormErrorMessage>{errors?.email?.message}</FormErrorMessage>
        <FormHelperText>
          We are obviously giving this straight to Facebook.
        </FormHelperText>
      </FormControl>
      <FormControl
        isInvalid={!!errors?.password?.message}
        errortext={errors?.password?.message}
        px='4'
        pb='4'
        isRequired
      >
        <FormLabel>Password</FormLabel>
        <Input
          ref={register}
          type='password'
          placeholder='Password'
          name='password'
        />
        <FormErrorMessage>{errors?.password?.message}</FormErrorMessage>
      </FormControl>
      <Button
        onClick={handleSubmit(onSubmit)}
        p='4'
        mx='4'
        mt='6'
        w='90%'
        colorScheme='blue'
        variant='solid'
        disabled={!!errors.email || !!errors.password}
      >
        Login
      </Button>
    </form>
  );
}
```

Let's import the `LoginForm` component into our `App.tsx` file so we can use it.

```typescript
import { Center, Flex } from '@chakra-ui/react';
import LoginForm from './LoginForm';

function App() {
  return (
    <Flex justify='center' h='100vh' w='100vw' align='center'>
      <Center w='100%'>
        <LoginForm />
      </Center>
    </Flex>
  );
}

export default App;
```

And that's it folks. That is how we validate a form using React Hook Form, Yup, and Chakra.

You can try a live demo on the sandbox below:
{% codesandbox chakra-ui-react-hook-form-yup-rrf8u %}