How to Validate Forms in React Native — a Personal Approach
What Have I Learned About the Forms Validation in React Native?
While developing an application you always learn new things: how to implement some feature that you’ve never created before, which tool is better to choose to develop with, etc. Just recently, I have encountered some problem with React Native. Well, being honest it wasn’t a problem at all — more like a choice I had to make. The issue was to choose the best way to validate forms in React Native. Some other related questions came up.
Okay, let’s get all my ducks in a row before we all get confused!
The challenge
- Validating forms in React Native
- Customizing the highlight of an
Invalid Field
- Ability to add different ways of notifying about an incorrectly filled form
Possible solutions
In short, the solutions are obvious:
#1. Use predefined libraries (redux forms, react-native-forms, tcomb-react-native)
Pluses:
The validation logic is already implemented.
Minuses:
The need to customize the layout of forms.
#2. «Reinvent the wheel»
Pluses:
The opportunity to implement the whole process of validation by yourself.
Minuses:
Considerable time costs.
So what have I chosen?
Definitely, a «wheel». I’m not looking for easy answers. Besides, it’s much more interesting to create something of your own.
Here’s the module structure:
Form
FormItem
Let’s see their core characteristics.
Form
Simple View
component with the ability to attach styles.FormItem
are its children.- The
Validate
function checks the validity of eachFormItem
.
FormItem
Simple View
component with the ability to attach styles.- The opportunity to define the validation method (regular expression or function).
- The possibility to define the field for validation.
- The ability to make the field optional (regardless of the validation)
- Works with deep nested objects.
How does it work?
To make this module work you need to go through a simple algorithm:
- Find all the required elements of
FormItem
. - If the
validationFunction
is defined, then use it only to validate the form. - If not, then check for existing
«»
,null
,false
,undefined
. IfregExp
is specified, then test/match works along with it.
Example
To get to know it closer simply look through the code below.
import React, { Component } from 'react';import { Text, View, TextInput, TouchableOpacity, Dimensions} from 'react-native';import { Form, FormItem } from 'react-native-form-validation';const width = Dimensions.get('window').width;class ComponentWithValue extends Component{ constructor(props){ super(props); } render(){ return ( <View style={this.props.style}> <TextInput style={styles.flex} value={this.props.value} onChange={this.props.onChange}/> </View> ); }}class FormTest extends Component { constructor(props){ super(props); this.state = { textInput1:'1', textInput2:'2', textInput3:'3', textInput4:'4', view1:'1' }; }textInput1Change(event){ this.setState({ textInput1:event.nativeEvent.text });}textInput2Change(event){ this.setState({ textInput2:event.nativeEvent.text });}textInput3Change(event){ this.setState({ textInput3:event.nativeEvent.text });}textInput4Change(event){ this.setState({ textInput4:event.nativeEvent.text });}submit(){ let submitResults = this.refs.form.validate();}customValidation(){ return true;}render(){ return ( <View style={styles.container}> <Form ref="form" shouldValidate={true} style={styles.flex}> <FormItem isRequired={true} regExp={/^\d+$/} style={styles.formInput}> <TextInput style={styles.firstInput} value={this.state.textInput1} onChange={this.textInput1Change.bind(this)}/> </FormItem> <FormItem isRequired={false} style={styles.formInput}> <View style={styles.flex}> <View style={styles.secondInputWrapper}> <TextInput style={styles.flex} value={this.state.textInput2} onChange={this.textInput2Change.bind(this)}/> </View> </View> </FormItem> <FormItem isRequired={true} validationFunction={this.customValidation.bind(this)}> <View style={styles.formItem}> <View style={styles.flex}> <View style={styles.flex}> <TextInput style={styles.flex} value={this.state.textInput3} onChange={this.textInput3Change.bind(this)}/> </View> <View /> </View> </View> </FormItem> <FormItem isRequired={true}> <ComponentWithValue style={styles.formItem} value={this.state.textInput4} onChange={this.textInput4Change.bind(this)}/> </FormItem> <FormItem isRequired={true} fieldToBeValidated={'test'}> <View style={styles.formItem} test={this.state.view1}> <Text> {this.state.view1}</Text> </View> </FormItem></Form><TouchableOpacity style={styles.submitBtn} onPress={this.submit.bind(this)}> <Text>Submit</Text></TouchableOpacity></View>);}}class SmartForm extends Component { render() { return ( <FormTest /> ); }}const styles = { container:{ alignItems:'center', justifyContent:'center', width, flex:1 }, flex:{ flex:1},formItem:{ width:300, height:50},formInput:{ width:300, height:50},firstInput:{ width:300, height:60},secondInputWrapper:{ width:300, height:50,},submitBtn:{ height:100, width:100}};
What’s the result?
Each solution has both strong and weak sides with no exception. Let me show it to you!
Pluses:
- Full control over validation.
- The module validates the form and returns the result. After executing the
Validate
method it’s easy to highlight the form in any way you like. - It’s easy to validate not only the
TextInput
, but also the usualText
,View
and other custom components.
Minuses:
- The layout needs to be done separately.
Conclusion
As you can see, I took up the challenge, got through some interesting choices and in the end I have found the best way to validate forms in React Native. Now you even know all the pros and cons of the possible choices. So make your own decision!
If you liked this, show your support by clapping us to share with other people on Medium.
Follow us on Facebook, Instagram, LinkedIn, Behance, Medium and visit our corporate blog for more news and articles on smart solutions.
Any questions? Feel free to contact us!