Form Validation in React Native with Formik and Yup Library

Form Validation in React Native with Formik and Yup Library

Introduction

Form validation is a crucial aspect of developing robust React Native applications. In this article, we'll explore how to implement form validation using two powerful and most popular libraries: Formik for managing forms and Yup for defining validation schemas.

Prerequisties

Before we start, ensure that you have Node.js and npm installed on your machine. Additionally, make sure you have Expo CLI installed, to install expo cli enter:

npm install -g expo-cli

Getting started

Now, let's create a new Expo project with app name as Login-form-demo

npx create-expo-app Login-form-demo

once the project is created, navigate to the project folder and open in your favorite code Editor, in my case it is Visual Studio Code:

cd Login-form-demo
code .

Creating the Login Form Component:

LoginForm.js

To maintain a level of abstraction, let's create a dedicated component for our login form. In the root of your project, create a new file named LoginForm.js. This component will encapsulate the login form logic. Let's just create a boilerplate code for now, in this component so that we can import this in app.js file

LoginForm.js

import { StyleSheet, Text, View } from 'react-native'
import React from 'react'

const loginForm = () => {
  return (
    <View>
      <Text>loginForm</Text>
    </View>
  )
}

const styles = StyleSheet.create({})

export default loginForm

Now, let's import and use the LoginForm component in your App.js file:

App.js

// Import React
import React from 'react';
import { View } from 'react-native';

// Import the LoginForm component
import LoginForm from './LoginForm';

const App = () => {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <LoginForm />
    </View>
  );
};

export default App;

By creating a separate LoginForm component, you keep your code organized and maintain a level of abstraction, making it easier to manage and scale your application.

Installing and Importing Libraries

Let's install Formikand Yup libraries in our project:

npm install formik yup

Now, go to LoginForm.js this is the component where all the code changes will come in the following steps. import the required libraries in your LoginForm.js

// Import React and necessary components
import React from 'react';
import { View, TextInput, Button, Text } from 'react-native';

// Import Formik and Yup
import { Formik } from 'formik';
import * as Yup from 'yup';

Defining the Validation Schema with Yup

Define a validation schema using Yup to specify the validation rules for the form fields. In this example, we'll create a schema for email and password fields:

const validationSchema = Yup.object().shape({
  email: Yup.string().email('Invalid email').required('Email is required'),
  password: Yup.string().required('Password is required'),
});

Creating the Login Form with Formik

Now, let's create a login form using Formik. The Formik component helps manage form state, validation, and submission:

const LoginForm = () => {
  return (
    <Formik
      initialValues={{ email: '', password: '' }}
      validationSchema={validationSchema}
      onSubmit={(values) => {
        // Handle login logic here, I am just logging the data in my console
        console.log(values);
      }}
    >
      {({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => (
        <View>
          <TextInput
            onChangeText={handleChange('email')}
            onBlur={handleBlur('email')}
            value={values.email}
            placeholder="Email"
          />
          {touched.email && errors.email && <Text style={{ color: 'red' }}>{errors.email}</Text>}

          <TextInput
            onChangeText={handleChange('password')}
            onBlur={handleBlur('password')}
            value={values.password}
            placeholder="Password"
            secureTextEntry
          />
          {touched.password && errors.password && <Text style={{ color: 'red' }}>{errors.password}</Text>}

          <Button onPress={handleSubmit} title="Login" />
        </View>
      )}
    </Formik>
  );
};

Phew! that looks really overwhelming to look at, you might even wonder why do I even need this in first place. Sure, I get it we are taking in only two inputs email and password but we have written more than 100 lines of code for its validation. But here's the thing, formik and yup will handle many more things than just the validation. Let's breakdown the formik components bit by bit so that we can understand it better.

1. <Formik> Component:

<Formik
  initialValues={{ email: '', password: '' }}
  validationSchema={validationSchema}
  onSubmit={(values) => {
    // Handle login logic here
    console.log(values);
  }}
>
  • initialValues: Specifies the initial values for the form fields. In this case, email and password are initialized as empty strings.

  • validationSchema: Assigns the previously defined Yup validation schema (validationSchema) to validate the form fields.

  • onSubmit: Handles the form submission logic. In this example, it logs the form values to the console. You can replace this with your actual login logic.

2. Render Prop Function:

{({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => (
  // JSX for rendering the form components
)}

The Formik component takes a render prop function that provides several useful functions and values:

  • handleChange and handleBlur: Functions to handle changes and blur events for the form fields.

  • handleSubmit: Function to handle the form submission. It triggers the logic defined in the onSubmit prop.

  • values: Object containing the current values of the form fields.

  • errors and touched: Objects providing information about validation errors and whether the fields have been touched.

3. Form Components:

<View>
  {/* Email Input */}
  <TextInput
    onChangeText={handleChange('email')}
    onBlur={handleBlur('email')}
    value={values.email}
    placeholder="Email"
  />
  {touched.email && errors.email && <Text style={{ color: 'red' }}>{errors.email}</Text>}

  {/* Password Input */}
  <TextInput
    onChangeText={handleChange('password')}
    onBlur={handleBlur('password')}
    value={values.password}
    placeholder="Password"
    secureTextEntry
  />
  {touched.password && errors.password && <Text style={{ color: 'red' }}>{errors.password}</Text>}

  {/* Login Button */}
  <Button onPress={handleSubmit} title="Login" />
</View>

Inside the render prop function, we define the JSX for rendering the form components:

  • Email Input: A TextInput component for the email field. It uses the handleChange, handleBlur, and values functions to manage its state. If the field is touched (touched.email) and there is an error (errors.email), a red error message is displayed.

  • Password Input: Similar to the email input, but for the password field. The secureTextEntry prop is used to hide the entered password.

  • Login Button: A Button component that triggers the form submission when pressed.

This structure ensures that the form state, validation, and submission logic are all managed by Formik, making the implementation concise and modular.

Styling and Customizing the Form

Feel free to customize the form components and styles according to your app's design guidelines. You can add additional styling, icons, or other UI elements to enhance the user experience.

Conclusion

That’s it; now, if you click the submit button and fill out the form, it will alert you to the entered values, and if you submit it blank, it will display an error message. In this tutorial, we've covered the basics of form validation in React Native using Formik and Yup. By integrating these libraries, you can create a robust and user-friendly form handling mechanism in your applications. Explore further customization options and refer to the official documentation for Formik and Yup for advanced features. For any query, you can get in touch with me via LinkedIn and twitter. Below you can find the code in GitHub Repository

Now you're ready to implement form validation in your React Native Expo app using Formik and Yup. Happy coding!