Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

React - Form Validation

Implementing form validation in React

Form validation is an essential aspect of web development that ensures the data entered by users is accurate and meets the requirements. This tutorial covers how to implement form validation in React, using both controlled and uncontrolled components.

Key Points:

  • Form validation ensures that user inputs meet specific criteria before submission.
  • Validation can be implemented using both controlled and uncontrolled components.
  • React provides tools to handle validation logic and display validation messages.

Controlled Component Validation

In controlled components, form data is handled by the component's state. You can implement validation logic in the event handlers that update the state.

// Controlled component validation
import React, { useState } from 'react';

function ControlledForm() {
    const [formValues, setFormValues] = useState({
        username: '',
        email: ''
    });
    const [errors, setErrors] = useState({});

    const handleChange = (event) => {
        const { name, value } = event.target;
        setFormValues({
            ...formValues,
            [name]: value
        });
    };

    const validate = () => {
        const newErrors = {};
        if (!formValues.username) {
            newErrors.username = 'Username is required';
        }
        if (!formValues.email) {
            newErrors.email = 'Email is required';
        } else if (!/\S+@\S+\.\S+/.test(formValues.email)) {
            newErrors.email = 'Email address is invalid';
        }
        return newErrors;
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        const validationErrors = validate();
        if (Object.keys(validationErrors).length > 0) {
            setErrors(validationErrors);
        } else {
            setErrors({});
            // Process form data
            console.log('Form submitted:', formValues);
        }
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>
                    Username:
                    <input type="text" name="username" value={formValues.username} onChange={handleChange} />
                </label>
                {errors.username && <span className="error">{errors.username}</span>}
            </div>
            <div>
                <label>
                    Email:
                    <input type="email" name="email" value={formValues.email} onChange={handleChange} />
                </label>
                {errors.email && <span className="error">{errors.email}</span>}
            </div>
            <button type="submit">Submit</button>
        </form>
    );
}

export default ControlledForm;

Uncontrolled Component Validation

In uncontrolled components, form data is handled by the DOM itself. You can use refs to access form values and implement validation logic before form submission.

// Uncontrolled component validation
import React, { useRef, useState } from 'react';

function UncontrolledForm() {
    const usernameRef = useRef(null);
    const emailRef = useRef(null);
    const [errors, setErrors] = useState({});

    const validate = () => {
        const newErrors = {};
        if (!usernameRef.current.value) {
            newErrors.username = 'Username is required';
        }
        if (!emailRef.current.value) {
            newErrors.email = 'Email is required';
        } else if (!/\S+@\S+\.\S+/.test(emailRef.current.value)) {
            newErrors.email = 'Email address is invalid';
        }
        return newErrors;
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        const validationErrors = validate();
        if (Object.keys(validationErrors).length > 0) {
            setErrors(validationErrors);
        } else {
            setErrors({});
            // Process form data
            console.log('Form submitted:', {
                username: usernameRef.current.value,
                email: emailRef.current.value
            });
        }
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>
                    Username:
                    <input type="text" ref={usernameRef} />
                </label>
                {errors.username && <span className="error">{errors.username}</span>}
            </div>
            <div>
                <label>
                    Email:
                    <input type="email" ref={emailRef} />
                </label>
                {errors.email && <span className="error">{errors.email}</span>}
            </div>
            <button type="submit">Submit</button>
        </form>
    );
}

export default UncontrolledForm;

Full Example

Here is a complete example of a form with validation managed with both controlled and uncontrolled components in a React application:

// App.js
import React, { useState, useRef } from 'react';

function App() {
    const [formValues, setFormValues] = useState({
        username: '',
        email: ''
    });
    const [errors, setErrors] = useState({});
    const usernameRef = useRef(null);
    const emailRef = useRef(null);

    const handleChange = (event) => {
        const { name, value } = event.target;
        setFormValues({
            ...formValues,
            [name]: value
        });
    };

    const validate = () => {
        const newErrors = {};
        if (!formValues.username && !usernameRef.current.value) {
            newErrors.username = 'Username is required';
        }
        if (!formValues.email && !emailRef.current.value) {
            newErrors.email = 'Email is required';
        } else if (!/\S+@\S+\.\S+/.test(formValues.email || emailRef.current.value)) {
            newErrors.email = 'Email address is invalid';
        }
        return newErrors;
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        const validationErrors = validate();
        if (Object.keys(validationErrors).length > 0) {
            setErrors(validationErrors);
        } else {
            setErrors({});
            // Process form data
            console.log('Form submitted:', {
                username: formValues.username || usernameRef.current.value,
                email: formValues.email || emailRef.current.value
            });
        }
    };

    return (
        <div className="container">
            <h1>Form Validation in React</h1>
            <form onSubmit={handleSubmit}>
                <div>
                    <label>
                        Username:
                        <input
                            type="text"
                            name="username"
                            value={formValues.username}
                            ref={usernameRef}
                            onChange={handleChange}
                        />
                    </label>
                    {errors.username && <span className="error">{errors.username}</span>}
                </div>
                <div>
                    <label>
                        Email:
                        <input
                            type="email"
                            name="email"
                            value={formValues.email}
                            ref={emailRef}
                            onChange={handleChange}
                        />
                    </label>
                    {errors.email && <span className="error">{errors.email}</span>}
                </div>
                <button type="submit">Submit</button>
            </form>
        </div>
    );
}

export default App;

Summary

In this tutorial, you learned how to implement form validation in React. Form validation ensures that user inputs meet specific criteria before submission. You learned how to handle validation using both controlled and uncontrolled components, including creating validation logic, displaying validation messages, and processing form data. Understanding form validation is essential for creating robust and user-friendly forms in React applications.