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 Formik
and 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
andpassword
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
andhandleBlur
: Functions to handle changes and blur events for the form fields.handleSubmit
: Function to handle the form submission. It triggers the logic defined in theonSubmit
prop.values
: Object containing the current values of the form fields.errors
andtouched
: 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 thehandleChange
,handleBlur
, andvalues
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!