Paramclasses Academy - Blog

Tutorials Details

←
Post 20 of 39
→

What is Form Validation in React Native ?

What is Form Validation in React Native ?

November 5, 2026

1. Introduction

Form validation is an important part of mobile application development.

Whenever users enter information into a form, an application should check whether the entered data is correct before accepting it.

For example:

  • A name field should not be empty.

  • An email address should follow a valid email format.

  • A mobile number should contain the required number of digits.

  • A password should meet minimum length requirements.

  • A confirm password field should match the password field.

In React Native, we can implement form validation using JavaScript conditions, React state, and TextInput components.

In this tutorial, we will build a complete Student Registration Form with validation.

2. What Is Form Validation?

Form validation is the process of checking user input before submitting a form.

Consider an email field.

If a user enters:

rahulgmail.com

The application should identify that the email address is incorrectly formatted.

A valid-looking example would be:

rahul@gmail.com

Similarly, if a password requires at least six characters, the application should reject shorter values.

3. Types of Form Validation

A. Required Field Validation

Checks whether the user has entered a value.

Example:

if (name.trim() === '') {
  error = 'Name is required';
}

B. Email Validation

Checks whether the email follows a basic email format.

const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

if (!emailPattern.test(email)) {
  error = 'Please enter a valid email';
}

C. Mobile Number Validation

Checks whether the mobile number contains exactly ten digits.

if (!/^[0-9]{10}$/.test(phone)) {
  error = 'Enter a valid 10-digit mobile number';
}

D. Password Validation

Checks whether the password meets the minimum length requirement.

if (password.length < 6) {
  error = 'Password must contain at least 6 characters';
}

E. Confirm Password Validation

Checks whether both password fields match.

if (password !== confirmPassword) {
  error = 'Passwords do not match';
}

4. Project Requirements

Before starting, make sure you have:

  • Node.js and npm installed.

  • Visual Studio Code installed.

  • Expo development environment configured.

  • Android Emulator or Expo Go.

  • Basic knowledge of JavaScript.

  • Basic knowledge of React Native components.

  • Understanding of useState and TextInput.

5. Create a React Native Project

Open your terminal and execute:

npx create-expo-app@latest FormValidationApp --template blank

Move into the project folder:

cd FormValidationApp

Open the project in Visual Studio Code:

code .

We will implement validation directly using React Native and JavaScript. No external validation library is required for this beginner project.

6. Understand the Application Structure

Our Student Registration Form will contain five input fields:

  1. Full Name

  2. Email Address

  3. Mobile Number

  4. Password

  5. Confirm Password

It will also contain:

  • A Register button.

  • Individual error messages below input fields.

  • A success message when all fields are valid.

The application flow:

       REGISTRATION FORM
               |
               |
        User Enters Data
               |
               |
         Click Register
               |
               v
        VALIDATE FIELDS
               |
         +-----+-----+
         |           |
       Invalid      Valid
         |           |
         v           v
    Show Errors   Submit Form
                     |
                     v
               Success Message

7. Create the Complete Form Validation Application

Open App.js and replace the existing code with the following complete code.

Complete App.js Code

import React, { useState } from 'react';

import {
  View,
  Text,
  TextInput,
  Pressable,
  StyleSheet,
  ScrollView,
  KeyboardAvoidingView,
  Platform,
  Alert,
} from 'react-native';

export default function App() {

  // Form input states

  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');

  // Error state

  const [errors, setErrors] = useState({});

  // Validation function

  const validateForm = () => {

    const newErrors = {};

    // Name validation

    if (!name.trim()) {
      newErrors.name = 'Full name is required';
    } else if (name.trim().length < 3) {
      newErrors.name = 'Name must contain at least 3 characters';
    }

    // Email validation

    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    if (!email.trim()) {
      newErrors.email = 'Email address is required';
    } else if (!emailPattern.test(email.trim())) {
      newErrors.email = 'Please enter a valid email address';
    }

    // Phone validation

    if (!phone.trim()) {
      newErrors.phone = 'Mobile number is required';
    } else if (!/^[0-9]{10}$/.test(phone)) {
      newErrors.phone = 'Enter a valid 10-digit mobile number';
    }

    // Password validation

    if (!password) {
      newErrors.password = 'Password is required';
    } else if (password.length < 6) {
      newErrors.password = 'Password must contain at least 6 characters';
    }

    // Confirm password validation

    if (!confirmPassword) {
      newErrors.confirmPassword = 'Please confirm your password';
    } else if (password !== confirmPassword) {
      newErrors.confirmPassword = 'Passwords do not match';
    }

    setErrors(newErrors);

    return Object.keys(newErrors).length === 0;
  };

  // Clear an individual field error

  const clearError = (field) => {
    setErrors((previousErrors) => ({
      ...previousErrors,
      [field]: '',
    }));
  };

  // Form submission

  const handleSubmit = () => {

    const isValid = validateForm();

    if (!isValid) {
      return;
    }

    Alert.alert(
      'Registration Successful',
      'All fields have passed frontend validation.'
    );

    console.log('Student Registration Data:', {
      name: name.trim(),
      email: email.trim(),
      phone: phone,
    });

  };

  return (

    <KeyboardAvoidingView
      style={styles.screen}
      behavior={Platform.OS === 'ios' ? 'padding' : undefined}
    >

      <ScrollView
        contentContainerStyle={styles.container}
        keyboardShouldPersistTaps="handled"
      >

        <Text style={styles.heading}>
          Student Registration
        </Text>

        <Text style={styles.subtitle}>
          Please enter your details correctly.
        </Text>

        {/* NAME FIELD */}

        <Text style={styles.label}>
          Full Name
        </Text>

        <TextInput
          style={[
            styles.input,
            errors.name ? styles.inputError : null,
          ]}
          placeholder="Enter your full name"
          value={name}
          onChangeText={(value) => {
            setName(value);
            clearError('name');
          }}
          autoCapitalize="words"
          maxLength={60}
        />

        {errors.name ? (
          <Text style={styles.errorText}>
            {errors.name}
          </Text>
        ) : null}

        {/* EMAIL FIELD */}

        <Text style={styles.label}>
          Email Address
        </Text>

        <TextInput
          style={[
            styles.input,
            errors.email ? styles.inputError : null,
          ]}
          placeholder="Enter your email"
          value={email}
          onChangeText={(value) => {
            setEmail(value);
            clearError('email');
          }}
          keyboardType="email-address"
          autoCapitalize="none"
          autoCorrect={false}
          maxLength={254}
        />

        {errors.email ? (
          <Text style={styles.errorText}>
            {errors.email}
          </Text>
        ) : null}

        {/* PHONE FIELD */}

        <Text style={styles.label}>
          Mobile Number
        </Text>

        <TextInput
          style={[
            styles.input,
            errors.phone ? styles.inputError : null,
          ]}
          placeholder="Enter 10-digit mobile number"
          value={phone}
          onChangeText={(value) => {
            setPhone(value);
            clearError('phone');
          }}
          keyboardType="number-pad"
          maxLength={10}
        />

        {errors.phone ? (
          <Text style={styles.errorText}>
            {errors.phone}
          </Text>
        ) : null}

        {/* PASSWORD FIELD */}

        <Text style={styles.label}>
          Password
        </Text>

        <TextInput
          style={[
            styles.input,
            errors.password ? styles.inputError : null,
          ]}
          placeholder="Create a password"
          value={password}
          onChangeText={(value) => {
            setPassword(value);
            clearError('password');
          }}
          secureTextEntry={true}
          autoCapitalize="none"
          autoComplete="new-password"
        />

        {errors.password ? (
          <Text style={styles.errorText}>
            {errors.password}
          </Text>
        ) : null}

        {/* CONFIRM PASSWORD FIELD */}

        <Text style={styles.label}>
          Confirm Password
        </Text>

        <TextInput
          style={[
            styles.input,
            errors.confirmPassword ? styles.inputError : null,
          ]}
          placeholder="Confirm your password"
          value={confirmPassword}
          onChangeText={(value) => {
            setConfirmPassword(value);
            clearError('confirmPassword');
          }}
          secureTextEntry={true}
          autoCapitalize="none"
          autoComplete="new-password"
        />

        {errors.confirmPassword ? (
          <Text style={styles.errorText}>
            {errors.confirmPassword}
          </Text>
        ) : null}

        {/* SUBMIT BUTTON */}

        <Pressable
          style={styles.button}
          onPress={handleSubmit}
        >
          <Text style={styles.buttonText}>
            REGISTER NOW
          </Text>
        </Pressable>

      </ScrollView>

    </KeyboardAvoidingView>

  );
}

// STYLES

const styles = StyleSheet.create({

  screen: {
    flex: 1,
    backgroundColor: '#F1F5F9',
  },

  container: {
    flexGrow: 1,
    justifyContent: 'center',
    padding: 24,
  },

  heading: {
    fontSize: 27,
    fontWeight: 'bold',
    color: '#1E293B',
    textAlign: 'center',
    marginBottom: 8,
  },

  subtitle: {
    fontSize: 14,
    color: '#64748B',
    textAlign: 'center',
    marginBottom: 25,
  },

  label: {
    fontSize: 14,
    fontWeight: '600',
    color: '#334155',
    marginBottom: 7,
    marginTop: 13,
  },

  input: {
    height: 52,
    backgroundColor: '#FFFFFF',
    borderWidth: 1,
    borderColor: '#CBD5E1',
    borderRadius: 9,
    paddingHorizontal: 14,
    fontSize: 15,
  },

  inputError: {
    borderColor: '#DC2626',
    borderWidth: 1.5,
  },

  errorText: {
    color: '#DC2626',
    fontSize: 12,
    marginTop: 5,
  },

  button: {
    backgroundColor: '#2563EB',
    padding: 16,
    borderRadius: 9,
    alignItems: 'center',
    marginTop: 28,
  },

  buttonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: 'bold',
  },

});

8. Understand the Important Code

A. Creating Form State Using useState

First, we create separate state variables for each input field.

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [password, setPassword] = useState('');

These variables store the information entered by the user.

Whenever the user types something, the corresponding setter function updates the state.

B. Creating an Error State

We use another state variable to store validation errors.

const [errors, setErrors] = useState({});

Initially, the error object is empty.

After validation, it may contain:

{
  name: 'Full name is required',
  email: 'Please enter a valid email address',
  phone: 'Mobile number is required'
}

Each key represents a field, and its value contains the corresponding error message.

C. Creating the validateForm() Function

This function checks all input fields.

const validateForm = () => {

  const newErrors = {};

  if (!name.trim()) {
    newErrors.name = 'Name is required';
  }

  if (!email.trim()) {
    newErrors.email = 'Email is required';
  }

  setErrors(newErrors);

  return Object.keys(newErrors).length === 0;
};

The newErrors object collects all validation errors.

Object.keys(newErrors).length checks how many errors exist.

  • If the result is zero, the form is valid.

  • If the result is greater than zero, the form contains errors.

D. Understanding trim()

The trim() method removes whitespace from the beginning and end of a string.

Example:

const name = '   Rahul Sharma   ';

console.log(name.trim());

Output:

Rahul Sharma

This prevents a user from submitting a name containing only spaces.

E. Understanding Email Validation

We use a regular expression to check the basic email format.

const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

if (!emailPattern.test(email)) {
  newErrors.email = 'Invalid email address';
}

The test() method returns either true or false.

This is a basic format check, not proof that the email address exists or belongs to the user.

F. Understanding Password Validation

We check the password length.

if (password.length < 6) {
  newErrors.password =
    'Password must contain at least 6 characters';
}

If the password contains fewer than six characters, the application displays an error.

G. Confirm Password Validation

The confirm password field should contain the same value as the password field.

if (password !== confirmPassword) {
  newErrors.confirmPassword =
    'Passwords do not match';
}

The !== operator checks whether two values are different.

H. Displaying Error Messages

We use conditional rendering to show error messages.

{errors.email ? (
  <Text style={styles.errorText}>
    {errors.email}
  </Text>
) : null}

If an email error exists, the message appears below the input field.

Otherwise, nothing is displayed.

I. Highlighting Invalid Input

We use conditional styling.

style={[
  styles.input,
  errors.email ? styles.inputError : null,
]}

When an error exists, the input border changes to red.

This helps users identify which field needs correction.

J. Clearing an Error When the User Types

We use a helper function:

const clearError = (field) => {
  setErrors((previousErrors) => ({
    ...previousErrors,
    [field]: '',
  }));
};

For example:

onChangeText={(value) => {
  setEmail(value);
  clearError('email');
}}

When the user edits the email field, its previous error message disappears.

The complete form is validated again when the user presses Register.

9. Run the Application

Start the Expo development server:

npx expo start

Then:

  1. Open Expo Go on your Android phone.

  2. Scan the QR code.

  3. Wait for the application to load.

  4. Enter the registration details.

  5. Press Register Now.

  6. Observe the validation messages.

  7. Correct the invalid fields.

  8. Submit the form again.

10. Practical Testing

Test the following cases.

Test 1: Empty Form

Leave every field empty and press Register Now.

Expected result:

  • Full name is required.

  • Email address is required.

  • Mobile number is required.

  • Password is required.

  • Confirm password is required.

Test 2: Invalid Name

Enter:

AB

Expected result:

Name must contain at least 3 characters

Test 3: Invalid Email

Enter:

rahulgmail.com

Expected result:

Please enter a valid email address

Test 4: Invalid Mobile Number

Enter:

12345

Expected result:

Enter a valid 10-digit mobile number

Test 5: Short Password

Enter:

123

Expected result:

Password must contain at least 6 characters

Test 6: Password Mismatch

Password:

rahul123

Confirm Password:

rahul456

Expected result:

Passwords do not match

Test 7: Valid Form

Use the following sample data:

Full Name: Rahul Sharma
Email: rahul@gmail.com
Mobile: 9876543210
Password: rahul123
Confirm Password: rahul123

Expected result:

Registration Successful

11. Common Errors and Solutions

Error 1: Error Messages Are Not Displayed

Possible reason: The error state is not updated.

Solution:

setErrors(newErrors);

Make sure this statement executes after validation.

Error 2: Email Validation Is Not Working

Possible reason: The regular expression is incorrect.

Solution:

const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

Error 3: Passwords Are Not Matching

Possible reason: The two values are different.

Solution:

if (password !== confirmPassword) {
  newErrors.confirmPassword = 'Passwords do not match';
}

Error 4: Error Message Does Not Disappear

Possible reason: The field's error is not cleared when the user types.

Solution:

onChangeText={(value) => {
  setEmail(value);
  clearError('email');
}}

Error 5: Keyboard Covers the Form

Possible reason: The form does not adjust when the keyboard opens.

Solution:

Use KeyboardAvoidingView and ScrollView to make the form easier to use on smaller screens.

12. Form Validation Libraries

For small beginner projects, JavaScript validation is sufficient.

For larger applications, developers often use dedicated form libraries.

React Hook Form

React Hook Form helps manage form values, validation, and submission with a structured API.

Official documentation:

https://react-hook-form.com/

Formik

Formik helps manage form state, validation, and submission.

Official React Native guide:

https://formik.org/docs/guides/react-native

Yup

Yup is a schema validation library. It can define reusable validation rules for fields.

Official documentation:

https://github.com/jquense/yup

These libraries are useful when forms become more complex and contain many fields.

13. Best Practices

  • Validate every required field.

  • Display clear error messages near the relevant input.

  • Use appropriate keyboard types.

  • Hide password values using secureTextEntry.

  • Use trim() where whitespace should not be accepted.

  • Avoid showing unnecessary validation errors.

  • Validate the form again before submission.

  • Keep validation logic separate from UI code as projects grow.

  • Never store plain-text passwords.

  • Never log passwords or other sensitive information.

  • Validate data again on the server before saving it.

Security note: Frontend validation improves the user experience, but it does not provide security by itself. A backend must independently validate submitted data.

14. Conclusion

In this tutorial, we created a complete Student Registration Form with React Native.

We implemented:

  • Required field validation.

  • Name validation.

  • Email validation.

  • Mobile number validation.

  • Password validation.

  • Confirm password validation.

  • Inline error messages.

  • Red error borders.

  • Error clearing when users edit fields.

  • Form submission after successful validation.

These concepts are essential when building Login Forms, Registration Forms, Contact Forms, Student Management Systems, and other real-world mobile applications.

15. Frequently Asked Questions

Q1. What is form validation in React Native?

Form validation checks whether the information entered by a user follows the application's requirements before submission.

Q2. Which component is used to collect user input?

The TextInput component is used to collect text from users.

Q3. How can we show an error message?

Use conditional rendering with a Text component.

Q4. What is the purpose of useState in form validation?

useState stores input values and validation errors so the interface updates when their values change.

Q5. How can we validate an email address?

We can use a regular expression to perform a basic email-format check.

Q6. How do we check whether two passwords match?

Compare the password and confirm password values using the !== operator.

Q7. Is frontend validation enough for a real application?

No. The backend must independently validate all submitted data.

Q8. Which libraries can be used for advanced form validation?

React Hook Form, Formik, and Yup are popular options for managing complex forms and validation rules.

←
Post 20 of 39
→