Sunday, March 12, 2023
HomeReactConstruct and validate kinds in React Native utilizing Formik and Yup by...

Construct and validate kinds in React Native utilizing Formik and Yup by Aman Mittal

Construct and validate kinds in React Native utilizing Formik and Yup

Printed on Oct 16, 2019


17 min learn



Formik and yup are nice improvement instruments to construct superior wanting UI kinds as per your React Native software wants. You’re going to get the complete context of this assertion by the top of this tutorial once I stroll you thru on this publish, to construct two kinds for login and signup screens, and showcase how simple it’s to validate them utilizing the mixture of libraries like Formik and Yup.

Be sure you obtain the supply code with a purpose to comply with this publish carefully and for a greater understanding of libraries like Formik and yup. The supply code file you might be downloading comprises the usage of navigation patterns like Stack and Change to meet the requirement of mimicking authentication move in a React Native app. It additionally comprises minimal code for 3 screens:

You’re going to proceed to construct on them. For full element on how I arrange this authentication move, please comply with the earlier publish How Authentication Move works in React Native apps utilizing React Navigation 4.x.

Desk of Contents


  • Necessities
  • Putting in the libraries
  • Creating reusable elements
  • Create a login kind
  • Add Formik to the login kind
  • Deal with kind submission
  • Validate kind with yup
  • Refactor error message
  • Disable Button when kind just isn’t legitimate
  • Present errors provided that contact for specified area
  • Present a loading indicator on Login button whereas submitting
  • A problem for you πŸ’ͺ
  • Conclusion



If you’ll code alongside, be sure you have already put in the next:

  • Nodejs (>=10.x.x) with npm/yarn put in.
  • expo-cli (>=3.x.x), beforehand often called create-react-native-app.
  • Mac customers may use an iOS simulator.
  • Home windows/Linux customers should be working an Android emulator.

To know extra about learn how to setup and run the simulator or the emulator in your native improvement surroundings go to React Native’s official documentation right here.

Putting in the libraries


Proper now, the bundle.json file from the earlier publish seems like the next. It comprises a primary Expo clean template and dependencies for react-navigation library.

1"dependencies": {

2 "expo": "^34.0.1",

3 "react": "16.8.3",

4 "react-dom": "^16.8.6",

5 "react-native": "",

6 "react-native-gesture-handler": "~1.3.0",

7 "react-native-reanimated": "~1.1.0",

8 "react-native-screens": "1.0.0-alpha.22",

9 "react-native-web": "^0.11.4",

10 "react-navigation": "4.0.0",

11 "react-navigation-stack": "1.5.1"

12 },

Set up the libraries which might be going for use to create login and signup kinds. Open up a terminal window and execute the next command.

yarn add formik yup react-native-elements

The UI library react-native-elements is a “Cross-Platform React Native UI Toolkit” that makes simple to construct varied interface elements in React Native apps with extra functionalities. It is going to velocity up the event course of for this demo.

Creating reusable elements


Inside elements/ listing create two new recordsdata known as: FormButton.js and FormInput.js. Each of those elements are going to be presentational and reusable in display elements. Open FormButton.js file, import the Button part react-native-elements library.

It’s a touchable factor that permits the consumer to work together with the system’s display and carry out the following motion. This tradition part will obtain props for styling and its type. The part library react-native-elements has alternative ways to type a button.


2import React from 'react';

3import { Button } from 'react-native-elements';


5const FormButton = ({ title, buttonType, buttonColor, ...relaxation }) => (

6 <Button

7 {...relaxation}

8 kind={buttonType}

9 title={title}

10 buttonStyle={{ borderColor: buttonColor, borderRadius: 20 }}

11 titleStyle={{ colour: buttonColor }}

12 />



15export default FormButton;

Subsequent, open FormInput.js file. Once more, it will be a customized part for a textual content enter area. Import the Enter factor from react-native-elements. It permits the consumer to enter the textual content in a kind UI. It receives props as properly and since utilizing Expo, vector-icons will be imported with out putting in a 3rd occasion dependency manually.

Lastly, discover how the remaining props are handed via an object utilizing relaxation operator. That is often known as relaxation parameter syntax. Be certain that the order of the props stays similar as beneath. That’s, the ...relaxation comes earlier than different props within the FormInput part, because it will not be capable of override these different properties.

1import React from 'react';

2import { Enter } from 'react-native-elements';

3import { StyleSheet, View } from 'react-native';

4import { Ionicons } from '@expo/vector-icons';


6const FormInput = ({

7 iconName,

8 iconColor,

9 returnKeyType,

10 keyboardType,

11 title,

12 placeholder,

13 worth,

14 ...relaxation

15}) => (

16 <View type={types.inputContainer}>

17 <Enter

18 {...relaxation}

19 leftIcon={<Ionicons title={iconName} measurement={28} colour={iconColor} />}

20 leftIconContainerStyle={types.iconStyle}

21 placeholderTextColor="gray"

22 title={title}

23 worth={worth}

24 placeholder={placeholder}

25 type={types.enter}

26 />

27 </View>



30const types = StyleSheet.create({

31 inputContainer: {

32 margin: 15

33 },

34 iconStyle: {

35 marginRight: 10

36 }



39export default FormInput;

Create a login kind


Now that the customized elements are all arrange, allow us to create a login display part. Open screens/Login.js file and import all required statements. Then, with out altering the state or any handler capabilities from the earlier base repo you downloaded and are following for this tutorial, allow us to straight dive into the render methodology of the Login part.

1import React from 'react';

2import { StyleSheet, SafeAreaView, View } from 'react-native';

3import { Button } from 'react-native-elements';

4import FormInput from '../elements/FormInput';

5import FormButton from '../elements/FormButton';


7export default class Login extends React.Element {

8 state = {

9 electronic mail: '',

10 password: ''

11 };


13 handleEmailChange = electronic mail => {

14 this.setState({ electronic mail });

15 };


17 handlePasswordChange = password => {

18 this.setState({ password });

19 };


21 onLogin = async () => {

22 const { electronic mail, password } = this.state;

23 strive {

24 if (electronic mail.size > 0 && password.size > 0) {

25 this.props.navigation.navigate('App');

26 }

27 } catch (error) {

28 alert(error);

29 }

30 };


32 goToSignup = () => this.props.navigation.navigate('Signup');

33 render() {

34 const { electronic mail, password } = this.state;


36 return (

37 <SafeAreaView type={types.container}>

38 <FormInput

39 title="electronic mail"

40 worth={electronic mail}

41 placeholder="Enter electronic mail"

42 autoCapitalize="none"

43 onChangeText={this.handleEmailChange}

44 iconName="ios-mail"

45 iconColor="#2C384A"

46 />

47 <FormInput

48 title="password"

49 worth={password}

50 placeholder="Enter password"

51 secureTextEntry

52 onChangeText={this.handlePasswordChange}

53 iconName="ios-lock"

54 iconColor="#2C384A"

55 />

56 <View type={types.buttonContainer}>

57 <FormButton

58 buttonType="define"

59 onPress={this.handleOnLogin}

60 title="LOGIN"

61 buttonColor="#039BE5"

62 />

63 </View>

64 <Button

65 title="Do not have an account? Signal Up"

66 onPress={this.goToSignup}

67 titleStyle={{

68 colour: '#F57C00'

69 }}

70 kind="clear"

71 />

72 </SafeAreaView>

73 );

74 }



77const types = StyleSheet.create({

78 container: {

79 flex: 1,

80 backgroundColor: '#fff'

81 },

82 buttonContainer: {

83 margin: 25

84 }


Discover, contained in the SafeAreaView there are two FormInput fields and two buttons, out of which, one is the customized button beforehand created. The properties on enter fields reminiscent of secureTextEntry and autoCapitalize are distinctive to every enter area. Thus, this the place the relaxation parameter syntax turns out to be useful. Additionally, discover how the kind of each buttons will make a UI distinction within the output beneath.

Add Formik to the login kind


Formik is a small library that helps kinds to be organized in React and React Native with the next issues:

  • it retains observe of kind’s state
  • handles kind submission through reusable strategies and handlers (reminiscent of handleChange, handleBlur, and handleSubmit)
  • handles validation and error messages out of the field

At instances it turns into onerous to handle and fulfill the above factors. Utilizing Formik, you possibly can perceive what precisely is occurring in kinds and write fewer traces of code. Created by Jared Palmer it has a fantastic API to refer.

To get began, open Login.js file and import the library.




4import { Formik } from 'formik';

Subsequent, contained in the SafeAreaView use Formik because the wrapper factor. It comes with totally different props to deal with kinds reminiscent of initialValues and onSubmit handler methodology. The initialValues accepts an object containing kind values. Within the case of the present kind, these values are going to be electronic mail and password. The onSubmit methodology accepts a operate that has these values as the primary argument to deal with the shape submission.

Lastly, the third methodology utilized in Formik is the render methodology itself. It follows the Render Prop sample. Check out the Login part beneath.

1export default class Login extends React.Element {

2 goToSignup = () => this.props.navigation.navigate('Signup');

3 render() {

4 return (

5 <SafeAreaView type={types.container}>

6 <Formik

7 initialValues={{ electronic mail: '', password: '' }}

8 onSubmit={values => {}}

9 >

10 {formikProps => (

11 <Fragment>

12 <FormInput

13 title="electronic mail"

14 worth={values.electronic mail}

15 onChangeText={formikProps.handleChange('electronic mail')}

16 placeholder="Enter electronic mail"

17 autoCapitalize="none"

18 iconName="ios-mail"

19 iconColor="#2C384A"

20 />

21 <FormInput

22 title="password"

23 worth={values.password}

24 onChangeText={formikProps.handleChange('password')}

25 placeholder="Enter password"

26 secureTextEntry

27 iconName="ios-lock"

28 iconColor="#2C384A"

29 />

30 <View type={types.buttonContainer}>

31 <FormButton

32 buttonType="define"

33 onPress={formikProps.handleSubmit}

34 title="LOGIN"

35 buttonColor="#039BE5"

36 />

37 </View>

38 </Fragment>

39 )}

40 </Formik>

41 <Button

42 title="Do not have an account? Signal Up"

43 onPress={this.goToSignup}

44 titleStyle={{

45 colour: '#F57C00'

46 }}

47 kind="clear"

48 />

49 </SafeAreaView>

50 );

51 }


The worth prop in every of the above enter fields is given the preliminary worth from the formikProps. It’s handed via every render operate that gives entry to the state of the shape as initialValues. It’s important to outline these values simply as you’d do within the state of a category part. Aside from that, it additionally offers entry to deal with the change of every enter area (when consumer varieties within the electronic mail or the password) and a way to submit the shape: handleSubmit.

You may refactor the present part into the next:


2 ({ handleChange, values, handleSubmit }) => (

3 <Fragment>

4 <FormInput

5 title="electronic mail"

6 worth={values.electronic mail}

7 onChangeText={handleChange('electronic mail')}

8 placeholder="Enter electronic mail"

9 autoCapitalize="none"

10 iconName="ios-mail"

11 iconColor="#2C384A"

12 />

13 <FormInput

14 title="password"

15 worth={values.password}

16 onChangeText={handleChange('password')}

17 placeholder="Enter password"

18 secureTextEntry

19 iconName="ios-lock"

20 iconColor="#2C384A"

21 />

22 <View type={types.buttonContainer}>

23 <FormButton

24 buttonType="define"

25 onPress={handleSubmit}

26 title="LOGIN"

27 buttonColor="#039BE5"

28 />

29 </View>

30 </Fragment>

31 );


On wanting again to the simulator you’ll discover that Login kind seems the identical however now on clicking the login button, nothing occurs. Allow us to make it work. The onSubmit prop handles the shape submission. Proper now, to see that the values of each enter area are being recorded, allow us to add an alert methodology.

1onSubmit={values => { alert(JSON.stringify(values))}}

Return to the login display and fill each enter fields and click on the login button. You’re going to get a dialog field stating the values of each electronic mail and password.

Deal with Kind Submission


Now allow us to add the logic to enter the app each time the consumer clicks the login button as an alternative of exhibiting the values they entered in a dialog field. First, add a way on the onSubmit prop on Formik factor.

1onSubmit={values => {this.handleSubmit(values)}}

Subsequent, outline the handleSubmit methodology earlier than the render operate.

1handleSubmit = values => {

2 if (values.electronic mail.size > 0 && values.password.size > 0) {

3 this.props.navigation.navigate('App');

4 }


The logic remains to be the identical because it was if you began constructing this login kind. The consumer can solely log in to the app if the electronic mail and password fields are usually not empty. The one distinction that the values for each fields had been derived from the preliminary state of the part earlier than.

The customized enter part doesn’t want the worth prop to be handed on individually.


2const FormInput = ({

3 iconName,

4 iconColor,

5 returnKeyType,

6 keyboardType,

7 title,

8 placeholder,

9 ...relaxation

10}) => (

11 <View type={types.inputContainer}>

12 <Enter

13 {...relaxation}

14 leftIcon={<Ionicons title={iconName} measurement={28} colour={iconColor} />}

15 leftIconContainerStyle={types.iconStyle}

16 placeholderTextColor="gray"

17 title={title}

18 placeholder={placeholder}

19 type={types.enter}

20 />

21 </View>


Validating kind with yup


The yup library is helpful to handle advanced validation when utilizing Formik in both React or React Native apps. Formik helps each synchronous and asynchronous kind validation. It has help for schema primarily based kind degree validation from yup.

Import the whole lot from the yup library with different import statements.

1import * as yup from 'yup';

If you’re accustomed to Nodejs improvement, you’ll find yup library is sort of much like one other validation library known as joi. Subsequent, allow us to outline a brand new object earlier than the Login class part known as validationSchema.

Since initialValues is an object, it’s a must to specify yup.object() and outline a form of the item. Notice that, contained in the form when defining enter fields, be sure their title corresponds the identical as described in initialValues. Subsequent, every area on this object is supported by a sequence of validation strategies offered by the yup API. The kind of each electronic mail and password goes to be a string because the methodology onChangeText return values as strings.

1const validationSchema = Yup.object().form({

2 electronic mail: Yup.string()

3 .label('E-mail')

4 .electronic mail('Enter a sound electronic mail')

5 .required('Please enter a registered electronic mail'),

6 password: Yup.string()

7 .label('Password')

8 .required()

9 .min(4, 'Password will need to have no less than 4 characters ')


Utilizing a library like Yup saves quite a lot of time, particularly if you shouldn’t have to outline customized validation strategies to verify for an enter area. For instance, within the above snippet, utilizing .electronic mail() robotically matches towards a regex as an alternative defining regex to verify the validity of an electronic mail enter area.

Additionally, for each legitimate methodology, you possibly can enter a customized return message that is proven in case of an error. Have a look at theΒ .required() once more on the electronic mail within the above code snippet. It is stating that when an electronic mail is not offered, this message handed in quotes can be proven because the error message. Equally, for password, when the size of the enter area is lower than 4 characters, it would show an error message.
The final step so as to add the validationSchema to work, is so as to add a prop with the identical title within the Formik factor.


2 initialValues={{ electronic mail: '', password: '' }}

3 onSubmit={values => {

4 this.handleSubmit(values)

5 }}


7 validationSchema={validationSchema}>

8 {*/ Relaxation of the code


Subsequent, formikProps additionally present errors to entry error messages.


2{({ handleChange, values, handleSubmit, errors }) => (

After every enter area, you’ll have to add a Textual content factor to show the error message. Import it from react-native after which after every enter area provides the next.


2 title='electronic mail'

3 worth={values.electronic mail}

4 onChangeText={handleChange('electronic mail')}

5 placeholder='Enter electronic mail'

6 autoCapitalize='none'

7 iconName='ios-mail'

8 iconColor='#2C384A'


10<Textual content type={{ colour: 'purple' }}>{errors.electronic mail}</Textual content>


12 title='password'

13 worth={values.password}

14 onChangeText={handleChange('password')}

15 placeholder='Enter password'

16 secureTextEntry

17 iconName='ios-lock'

18 iconColor='#2C384A'

19 />

20<Textual content type={{ colour: 'purple' }}>{errors.password}</Textual content>

Attempt to click on the login button with out coming into particulars in any enter area.

Discover, how each the customized error message for the electronic mail area and a default message for password is displayed. Now, attempt to enter an invalid string within the electronic mail and a password of fewer than 4 characters after which submit the login button.

Discover that the error messages change and the proper error message is displayed.

Refactor error message


On this part, allow us to create a reusable presentational part to show the error messages. Open elements/ErrorMessage.js file and add the next.

1import React from 'react';

2import { View, Textual content, StyleSheet } from 'react-native';


4const ErrorMessage = ({ errorValue }) => (

5 <View type={types.container}>

6 <Textual content type={types.errorText}>{errorValue}</Textual content>

7 </View>



10const types = StyleSheet.create({

11 container: {

12 marginLeft: 25

13 },

14 errorText: {

15 colour: 'purple'

16 }



19export default ErrorMessage;

Subsequent, return to the Login.js file, import this part. Beneath every enter area the place there’s a Textual content factor, change it with the newly created customized ErrorMessage.


2 title='electronic mail'

3 worth={values.electronic mail}

4 onChangeText={handleChange('electronic mail')}

5 placeholder='Enter electronic mail'

6 autoCapitalize='none'

7 iconName='ios-mail'

8 iconColor='#2C384A'


10<ErrorMessage errorValue={errors.electronic mail} />


12 title='password'

13 worth={values.password}

14 onChangeText={handleChange('password')}

15 placeholder='Enter password'

16 secureTextEntry

17 iconName='ios-lock'

18 iconColor='#2C384A'

19 />

20<ErrorMessage errorValue={errors.password} />

The error messages at the moment are correctly aligned with the enter fields.

Disable Button when kind just isn’t legitimate


Formik offers a faster strategy to disable the submit button till there isn’t a error proven for any enter area. That is finished through the prop worth of isValid which returns true when there are not any errors. The disabled property is added to the FormButton, which is the place react-native-elements shine.

1 {({ handleChange, values, handleSubmit, errors, isValid, isSubmitting }) => (

2 <Fragment>

3 {*/ Res of the code stays similar












Discover that how the color of the button is modified to gray and it’s not clickable in any respect.

However coming into values for enter fields it comes again to life.

Present errors provided that contact for particular area


You probably have seen that the present state of the shape exhibits errors for each fields even when the consumer is coming into the primary area and hasn’t but seen what’s required within the second area.

To repair this, allow us to use two touched and handleBlur from formikProps.


2 handleChange,

3 values,

4 handleSubmit,

5 errors,

6 isValid,

7 isSubmitting

8 touched,

9 handleBlur,

10}) => ()

ThehandleBlur is handed as the worth to the onBlur prop on the enter area. This prop is used to trace whether or not an enter area has been touched by the consumer or not β€” the touched tracks what fields have been touched. Utilizing the mixture of each, you may get the next conduct.

Right here is the code snippet on how to do that. On every enter area, add the onBlur prop with the corresponding worth handed to handleBlur methodology.


2onBlur={handleBlur('electronic mail')}




Subsequent, when displaying the error message, modify it’s as follows for each fields.


2<ErrorMessage errorValue={touched.electronic mail && errors.electronic mail} />



5<ErrorMessage errorValue={touched.password && errors.password} />

Present a loading indicator on Login button whereas submitting


Subsequent, when submitting the login credentials, you don’t want the consumer to press the button twice. formikProps has an answer for this too. Utilizing isSubmitting you possibly can observe that when the shape is is in submitting section. Normally, in real-time software, this submitting section will rely on the asynchronous community name to the server. On the disabled prop, you need to use an OR situation to unravel this difficulty.

1disabled= isSubmitting

To imitate an API name, add a setTimeout operate to the handleSubmit methodology.

1handleSubmit = values => {

2 if (values.electronic mail.size > 0 && values.password.size > 0) {

3 setTimeout(() => {

4 this.props.navigation.navigate('App');

5 }, 3000);

6 }


Now observe how the button will get disabled when it’s touched.

You may add a loading indicator to the button, due to the prop with the identical title out there in react-native-elements.

1loading = { isSubmitting };

A problem for you πŸ’ͺ


Utilizing the information obtained from this tutorial, get it to work and construct a signup kind that appears like beneath with for 4 enter fields:

  • Identify of the consumer
  • E-mail
  • Password
  • A affirm password

The problem right here is to verify each fields: password and confirmPassword matches and an acceptable error message are proven is they don’t match. To search out the answer, lookout for the following publish, the place you’re going to get the reply to this drawback in addition to some extra functionalities such dealing with error when the enter area just isn’t of kind string.

Here’s a teaser:



Congratulations πŸŽ‰

You simply realized learn how to create, deal with, and validate kinds in React Native utilizing Formik and Yup. I hope in your manufacturing React Native apps, some little methods used on this tutorial reminiscent of in dealing with buttons and utilizing loading indicators assist. You will see the code for this tutorial together with the finished problem on the this Github repo launch.

Vital assets used to jot down this tutorial:

I am a software program developer and a technical author. On this weblog, I write about Technical writing, Node.js, React Native and Expo.

At the moment, working at Expo. Beforehand, I’ve labored as a Developer Advocate, and Senior Content material Developer with corporations like Draftbit, Vercel and Crowdbotics.


Most Popular

Recent Comments