React Js Form Handling : Lesson-11

Introduction

Handling forms in React is a crucial skill for building interactive and dynamic web applications. React simplifies form management through its stateful components, providing a more straightforward way to capture and utilize user input. Below are detailed notes on handling forms in React, including the basics, controlled components, handling multiple inputs, and form validation.

Introduction to Forms in React

In React, forms maintain their own state, taking input from the user and processing it as required. React offers a way to manage this input state, making it easier to handle form submissions and input validations.

This guide will progressively show you how to manage form inputs, starting from a single input field to a more complex form containing various types of inputs. We’ll explore the evolution from handling inputs individually to a more optimized approach using a single event handler.

Controlled Components

In React, we can use controlled components to manage form input. These components have a value and onChange property that we can set. We can use this to handle the input value change.

Handling a Single Input

Let’s start with a simple example where we capture the value from one input field and display it as the user types.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import React, { useState } from 'react';

function App() {
    const [inputValue, setInputValue] = useState('');

    const handleChange = (event) => {
        setInputValue(event.target.value);
    };

    return (
        <div>
            <input
                type="text"
                value={inputValue}
                onChange={handleChange}
            />
            <p>{inputValue}</p>
        </div>
    );
}

In the above code, we define a state variable inputValue and a function handleChange to handle the input value change. We also import the useState hook from React.

Handling Multiple Inputs

Now let’s take a more complex example, where we capture the values from multiple input fields and display them as the user types.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import React, { useState } from 'react';

function App() {
    const [nameValue, setNameValue] = useState('');
    const [emailValue, setEmailValue] = useState('');

    const handleNameChange = (event) => {
        setNameValue(event.target.value);
    };

    const handleEmailChange = (event) => {
        setEmailValue(event.target.value);
    };

    return (
        <div>
            <input
                type="text"
                value={nameValue}
                onChange={handleNameChange}
            />
            <input
                type="email"
                value={emailValue}
                onChange={handleEmailChange}
            />
            <p>Name: {nameValue}</p>
            <p>Email: {emailValue}</p>
        </div>
    );
}

In the above code, we define two state variables nameValue and emailValue and two event handlers handleNameChange and handleEmailChange. We also import the useState hook from React.

While this works, it’s not the most optimized approach, especially as forms grow in complexity.

Handling Multiple Inputs with Single Event Handler

Now let’s take a more optimized approach where we capture the values from multiple input fields and display them as the user types. We’ll use a single event handler to handle all input changes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React, { useState } from 'react';

function App() {
    const [inputValues, setInputValues] = useState({
        name: '',
        email: '',
    });

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

    return (
        <div>
            <input
                type="text"
                name="name"
                value={inputValues.name}
                onChange={handleChange}
            />
            <input
                type="email"
                name="email"
                value={inputValues.email}
                onChange={handleChange}
            />
            <p>Name: {inputValues.name}</p>
            <p>Email: {inputValues.email}</p>
        </div>
    );
}

In the above code, we define an object inputValues and a function handleChange to handle the input value change. We also import the useState hook from React.

Handling Complex Forms

Now, let’s tackle a form that includes various types of inputs: text, password, email, radio buttons for gender, checkboxes for hobbies, and a textarea and select box for country.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
import React, { useState } from 'react';

function App() {
    const [inputValues, setInputValues] = useState({
        name: '',
        email: '',
        password: '',
        gender: '',
        hobbies: [],
        country: '',
    });

    const handleCheckboxChange = (event) => {
        const { name, checked } = event.target;
        setInputValues((prevInputValues) => ({
            ...prevInputValues,
            [name]: checked,
        }));
    };

    const handleSelectChange = (event) => {
        const { name, value } = event.target;
        setInputValues((prevInputValues) => ({
            ...prevInputValues,
            [name]: value,
        }));
    };

    return (
        <div>
            <input
                type="text"
                name="name"
                value={inputValues.name}
                onChange={handleChange}
            />
            <input
                type="email"
                name="email"
                value={inputValues.email}
                onChange={handleChange}
            />
            <input
                type="password"
                name="password"
                value={inputValues.password}
                onChange={handleChange}
            />
            <input
                type="radio"
                name="gender"
                value="male"
                checked={inputValues.gender === 'male'}
                onChange={handleChange}
            />
            <input
                type="radio"
                name="gender"
                value="female"
                checked={inputValues.gender === 'female'}
                onChange={handleChange}
            />
            <input
                type="checkbox"
                name="hobby"
                value="music"
                checked={inputValues.hobbies.includes('music')}
                onChange={handleCheckboxChange}
            />
            <input
                type="checkbox"
                name="hobby"
                value="reading"
                checked={inputValues.hobbies.includes('reading')}
                onChange={handleCheckboxChange}
            />
            <input
                type="checkbox"
                name="hobby"
                value="traveling"
                checked={inputValues.hobbies.includes('traveling')}
                onChange={handleCheckboxChange}
            />
            <select
                name="country"
                value={inputValues.country}
                onChange={handleSelectChange}
            >
                <option value="">Select Country</option>
                <option value="india">India</option>
                <option value="usa">USA</option>
                <option value="uk">UK</option>
            </select>
            <p>Name: {inputValues.name}</p>
            <p>Email: {inputValues.email}</p>
            <p>Password: {inputValues.password}</p>
            <p>Gender: {inputValues.gender}</p>
            <p>Hobbies: {inputValues.hobbies.join(', ')}</p>
            <p>Country: {inputValues.country}</p>

        </div>
    );
}

We can use the handleCheckboxChange and handleSelectChange functions to handle the input value change for checkboxes and select boxes, respectively. By this way, we can capture the values from multiple input fields and display them as the user types.

uncontrolled components

Uncontrolled components in React are another way to handle form inputs, providing an alternative to the controlled component approach. Unlike controlled components, where form data is handled by the React component’s state, uncontrolled components allow the DOM itself to manage the form data. This approach can be simpler and more straightforward in certain scenarios, especially for traditional HTML form behaviors.

Understanding Uncontrolled Components

In uncontrolled components, you use a ref to directly access the DOM element, rather than storing its value in the state. This means you’re working more closely with the traditional HTML way of handling form inputs.

Why Use Uncontrolled Components? There are a few scenarios where uncontrolled components might be preferable:

  • When you need to integrate React with non-React code that expects to work with the DOM directly.
  • For simple forms where direct access to the DOM is more straightforward.
  • When you require a quick and dirty solution without needing a full-blown controlled component setup. Using Refs to Access Inputs

To manage uncontrolled components, React provides the useRef hook, which allows you to directly access a DOM element. You assign a ref to an input element, and then you can access its value without needing to sync it with the React state.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import React, { useRef } from 'react';

function App() {
  const inputRef = useRef(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    const name = inputRef.current.value;
    alert(`Hello, ${name}!`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

In this example, we use the useRef hook to assign a ref to an input element, and then we can access its value without needing to sync it with the React state.

Default Values

Uncontrolled components can also handle default values more straightforwardly. You can directly set a defaultValue prop on an uncontrolled <input>, which behaves similarly to setting the value prop on a controlled input, but only sets the initial value.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import React, { useRef } from 'react';

function App() {
  const inputRef = useRef(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    const name = inputRef.current.value;
    alert(`Hello, ${name}!`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" defaultValue="John Doe" ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

In this example, we use the useRef hook to assign a ref to an input element, and then we can directly set its defaultValue prop.

File Input

Uncontrolled components are particularly useful when dealing with file inputs since file inputs are read-only and don’t typically have an equivalent state management requirement.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import React, { useRef } from 'react';

function App() {
  const inputRef = useRef(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    const file = inputRef.current.files[0];
    alert(`File: ${file.name}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="file" ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

In this example, we use the useRef hook to assign a ref to an input element, and then we can access its value without needing to sync it with the React state.

Uncontrolled components offer a more straightforward way to handle form inputs in certain scenarios, relying on the DOM to manage the form data. This can be particularly useful for integrating with non-React code, handling simple forms, or when working with file inputs. However, it’s essential to choose between controlled and uncontrolled components based on the specific needs of your application. Controlled components give you more control over the form’s behavior, making them more suitable for complex forms and situations where you need to validate user input or have more complex interactions.

Conclusion

We can handle form inputs in React in a variety of ways, including: controlled, uncontrolled. we need to choose between them based on the specific needs of the application. Controlled components provide more control over the form’s behavior, while uncontrolled components offer a more straightforward and direct way to handle form inputs.

updatedupdated2024-04-242024-04-24
comments powered by Disqus