Handling Forms in ReactJS the right way

Hello everyone, recently I came across a new way to handle React forms, maybe its something you know, maybe you've been doing this for years and think I am an Idiot for not knowing this earlier, but it is what it is so let's go.

Using react forms the old way

Let's consider a simple signup form that contains only 3 fields namely username, email, and password. Here's how I used to use forms earlier.

import React,{useState} from 'react';
const SignUp = () => {
    const [username,setUsername] = useState("");
    const [password,setPassword] = useState("");
    const [email,setEmail] = useState("");

    const handleEmailChange(e){
        setEmail(e.target.value);
    }
    const handlePasswordChange(e){
        setPassword(e.target.value);
    }
    const handleUsernameChange(e){
        setUsername(e.target.value);
    }
    return(
        <form>
            <input type="text" placeholder="username" onChange={handleUsernameChange} value={username}/>
            <input type="email" placeholder="email" onChange={handleEmailChange} value={email}/>
            <input type="password" placeholder="password" onChange={handlePasswordChange} value={password}/>
            <input type="submit" value="Submit"/>
        </form>
    );
}

Maybe you think wtf is this guy and why is the code is so bad. There's only one thing I can say to you, sorry. To the other people who think there's nothing wrong with the code, prepare to get your mind blown.

Let's look at the problems with the code first-

  1. Its a lot of state variables for handling a form, especially if you think about bigger forms with 10s of fields.
  2. The handleChange functions are totally redundant and can be easily refactored.

So, now let's look at the amazing code to handle forms -

import React,{useState} from 'react';
const SignUp = () => {
const [formData, setFormData] = useState({
    username: "",
    email: "",
    password: "",
});

    const handleChange = (e)=> {
        const newFormData = {
            ...formData,
            [e.target.name]:e.target.value
        };
        setFormData(newFormData);
    }

    return(
             <form>
            <input type="text" name="username" placeholder="username" onChange={handleUsernameChange} value={username}/>
            <input type="email" name="email" placeholder="email" onChange={handleEmailChange} value={email}/>
            <input type="password"  name="password" placeholder="password" onChange={handlePasswordChange} value={password}/>
            <input type="submit" value="Submit"/>
        </form>
    );
}

Beautiful code, Right? Well, when I found it I thought it was amazing and worth sharing. But before you leave, make sure that the formData's keys are same as the input's name, else you're code won't work properly.


That's pretty much it. Thank you for reading. Bye