Building forms with Formik in react native

Photo by Kelly Sikkema on Unsplash
Photo by Kelly Sikkema on Unsplash

Building form is one of the part of UI development that takes a lot of time to deal with. Every field should be validated, values should be set and then sent to the final form submission.

There can also be multiple form validations for a single field. And sometimes we need to deal with multiple events like Blur and Change events.

To make this process easy and less tedious, we can use formik – a great library to build forms easily.

Today we are going to learn how to build forms with formik with react native.

Setup

Let’s do the usual react native setup first

npx react-native init formikApp
cd formikApp
npm i formik --save
react-native run-android

Let’s go to the App.js and change the code to get the below screen –

If you want to get ahead and check the code already , you can clone the repo from here

import React from 'react';
import {
SafeAreaView,
StyleSheet,
View,
TextInput,
Button
} from 'react-native';

const App = () => {
 return (
  <SafeAreaView style={{flex: 1}}>
   <View style={styles.container}>
    <TextInput
     style={styles.input}
     placeholder="Email"
    />
    <TextInput
     style={styles.input}
     placeholder="Password"
    />
    <Button color="blue" style={styles.button} title="Submit" />
   </View>
  </SafeAreaView>
 );
};

const styles = StyleSheet.create({
 container : {
  flex: 1,
  justifyContent: 'center',
  alignItems: 'center',
  },
  input : {
   borderWidth: 1,
   borderColor: 'grey',
   height: 40,
   width: '80%',
   marginVertical: 10,
   padding: 10
   },
  button: {
   borderColor: 'grey',
   borderWidth: 1,
   height: 40,
   width: 40,
   backgroundColor: 'grey'
  }
 });

export default App;

Handling events with Formik

Now it’s the time to add the functions to capture blur , submit and change events

Formik provides the props to capture events like handleChange, handleBlur, handleSubmit.

It provides values to bind the form values. Like in the code below.

<TextInput
          style={styles.input}
          placeholder="Password"
          value={values.password}
          onChangeText={handleChange('password')}
          onBlur={handleBlur('password')}
        />

We can also provide initialValues to the values as well.

import React from 'react';
import {
  SafeAreaView,
  StyleSheet,
  View,
  TextInput,
  Button,
  Alert,
  Text,
} from 'react-native';
import { Formik } from 'formik';

const App = () => {
  return (
    <Formik
      initialValues = {{email: '', password: ''}}
      onSubmit={values => Alert.alert(JSON.stringify(values))}
    >

    {({ handleChange, handleBlur, values, handleSubmit, errors }) => (<SafeAreaView style={{flex: 1}}>
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          placeholder="Email"
          value={values.email}
          onChangeText={handleChange('email')}
          onBlur={handleBlur('email')}
        />
        <TextInput
          style={styles.input}
          placeholder="Password"
          value={values.password}
          onChangeText={handleChange('password')}
          onBlur={handleBlur('password')}
        />
        <Button onPress={handleSubmit} color="blue" style={styles.button} title="Submit" />
      </View>
    </SafeAreaView>)}
    </Formik>
  );
};

const styles = StyleSheet.create({
  container : {
    flex: 1, 
    justifyContent: 'center',
    alignItems: 'center',
  }, input : {
    borderWidth: 1,
    borderColor: 'lightgrey',
    height: 40,
    width: '80%',
    marginVertical: 10,
    padding: 10
  }, button: {
    borderWidth: 1,
    height: 40,
    width: 40,
  }, errorMsg: {
    color: 'red',
    margin: 10,
  }
  
});

export default App;

If you click on the submit button now, you will see the alert with the email and the password provided.

Adding Validation to the form

Formik uses Yup to help with the validation schemas.

npm i yup --save

We can add the validation schema in the Formik component.

<Formik
      initialValues = {{email: '', password: ''}}
      onSubmit={values => Alert.alert(JSON.stringify(values))}
      validationSchema = {formSchema}
    >...</Formik>

Now let’s defing the formSchema

const formSchema = Yup.object().shape({
  email: Yup.string().email('Invalid Email').required('Email is required'),
  password: Yup.string().min(6,'Password must be 6 digits longs').required('Password is required')
})

Here we are addressing the ’email’ key as the string and email() checks whether the values.email is a valid email address or not. If values.email is not a valid email , we get the error in errors.email.

We can also set the custom email error as argument in email() like below.

email('Invalid Email');

required() => makes the values to be compulsorily filled.

min() -> defines the minimum number of letters

Errors can be checked like this

<Text style={styles.errorMsg}>{errors.email}</Text>

It we put all the code together, we can see the error messages showing when the email is empty or invalid.

import React from 'react';
import {
  SafeAreaView,
  StyleSheet,
  View,
  TextInput,
  Button,
  Alert,
  Text,
} from 'react-native';
import { Formik } from 'formik';
import * as Yup from 'yup';

const formSchema = Yup.object().shape({
  email: Yup.string().email('Invalid Email').required('Email is required'),
  password: Yup.string().min(6,'Password must be 6 digits longs').required('Password is required')
})

const App = () => {
  return (
    <Formik
      initialValues = {{email: '', password: ''}}
      onSubmit={values => Alert.alert(JSON.stringify(values))}
      validationSchema = {formSchema}
    >

    {({ handleChange, handleBlur, values, handleSubmit, errors }) => (<SafeAreaView style={{flex: 1}}>
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          placeholder="Email"
          value={values.email}
          onChangeText={handleChange('email')}
          onBlur={handleBlur('email')}
        />
        <Text style={styles.errorMsg}>{errors.email}</Text>
        <TextInput
          style={styles.input}
          placeholder="Password"
          value={values.password}
          onChangeText={handleChange('password')}
          onBlur={handleBlur('password')}
        />
        <Text style={styles.errorMsg}>{errors.password}</Text>
        <Button onPress={handleSubmit} color="blue" style={styles.button} title="Submit" />
      </View>
    </SafeAreaView>)}
    </Formik>
  );
};

const styles = StyleSheet.create({
  container : {
    flex: 1, 
    justifyContent: 'center',
    alignItems: 'center',
    width: '80%',
    alignSelf:'center'
  }, input : {
    borderWidth: 1,
    borderColor: 'lightgrey',
    height: 40,
    width: '100%',
    marginVertical: 10,
    padding: 10
  }, button: {
    borderWidth: 1,
    height: 40,
    width: 40,
  }, errorMsg: {
    color: 'red',
    marginVertical: 5,
    alignSelf:'flex-start'
  }
  
});

export default App;

Hope you enjoyed this post and get to learn that how formik can be useful.

You can clone this repo from here.

Thanks for reading! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *