Let's head on to see how forms are dealt in reactJS, and major takeaway as controlled and multiple inputs.
Forms ๐
Forms are collections of labels, input areas as well a button. So the user data provided in these input areas are to be used somewhere else in the application.
So here we see a scope for state management for the input areas value attribute.
Value attribute manipulation
Main focus according to our heading would be for sure the value attribute, rest of those are common in vanilla javascript.
As far the state management is concerned input areas value is set as a state variable in the component and whenever the user changes the value the state changes.
So as a final result the user data is preserved throughout the component and to be used wherever the data is required.
Flexible user input
Since we got questions regarding the complexity that may rise due to increased inputs and the state management issues.
So for different use cases we got different approaches, let's see em:
- Controlled Inputs
- Multiple Inputs
Controlled Inputs
For least inputs it's right to use state values to link to the value attribute in input areas, and whenever the user data changes the state value changes. So for controlled or least inputs we use straight forward approach.
Here's an example for managing the user's first name
<input type="text" id='firstName' name='firstName' value={firstName}
onChange={(e) => {
setFirstName(e.target.value)
}} />
Set the value attribute to a state value (firstName) and on change set the state to current value. So that the user data is preserved in the firstName state value.
Lets look into a use case to display the user detail filled on a form.
import React, { useState } from 'react';
const ControlledInputs = () => {
const [firstName, setFirstName] = useState(''); // for input area's
const [email, setEmail] = useState('');
const [people, setPeople] = useState([]);
const handleSubmit = (e) => {
e.preventDefault(); //prevents the reloading of the page
if (firstName && email) {
const person = { id: new Date().getTime().toString(), firstName, email };
// set id to be any unique value
setPeople((people) => {
return [...people, person];
});
setFirstName(''); //clears the input fields after submission
setEmail('');
} else {
alert('please enter data');
}
}
return <>
<article>
<form action="" className='form' onSubmit={handleSubmit}>
<div className="form-control">
<label htmlFor="firstName">Name : </label>
<input type="text" id='firstName' name='firstName' value={firstName} onChange={(e) => {
setFirstName(e.target.value)
}} /> //were magic happens
</div>
<div className="form-control">
<label htmlFor="email">Email : </label>
<input type="email" id='email' name='email' value={email} onChange={(e) => {
setEmail(e.target.value)
}} />
</div>
<button type='submit'>Add Person</button>
</form>
</article>
{
people.map((person) => { //for each person in people object display data
const { id, firstName, email } = person;
return <div className="item" key={id}>
<h4>{firstName}</h4>
<p>{email}</p>
</div>
})
}
</>
};
export default ControlledInputs;
Multiple Inputs
So far we have seen for controlled or minimal users data, if we got an survey form with 10 input areas we gotta use 10 state values for the same, which makes the process and managerial cumbersome.
For complex approaches like the above mentioned we gotta use a combined state with object that takes in all single data provided by the user.
Lets see an example with more than two input fields similar to the above use case.
import React, { useState } from 'react';
const MultipleInputs = () => {
const [firstName, setFirstName] = useState('');
const [email, setEmail] = useState('');
const [age, setAge] = useState('');
const [person, setPerson] = useState({ firstName: '', email: '', age: '' });
//combine the single state values to an object
const [people, setPeople] = useState([]);
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setPerson({ ...person, [name]: value });
}
const handleSubmit = (e) => {
e.preventDefault();
if (person.firstName && person.email && person.age) {
const newPerson = { ...person, id: new Date().getTime().toString() }
setPeople([...people, newPerson]);
setPerson({ firstName: '', email: '', age: '' }); //clear fields
}
}
return (
<>
<article>
<form className='form'>
<div className='form-control'>
<label htmlFor='firstName'>Name : </label>
<input
type='text'
id='firstName'
name='firstName'
value={person.firstName}
onChange={handleChange}
/>
</div>
<div className='form-control'>
<label htmlFor='email'>Email : </label>
<input
type='email'
id='email'
name='email'
value={person.email}
onChange={handleChange}
/>
</div>
<div className='form-control'>
<label htmlFor='age'>Age : </label>
<input
type='number'
id='age'
name='age'
value={person.age}
onChange={handleChange}
/>
</div>
<button type='submit' onClick={handleSubmit}>add person</button>
</form>
{people.map((person, index) => {
const { id, firstName, email, age } = person;
return (
<div className='item' key={id}>
<h4>{firstName}</h4>
<p>{email}</p>
<p>{age}</p>
</div>
);
})}
</article>
</>
);
};
export default MultipleInputs;
Major Takeaway
Manipulate the value attribute in input fields such that the user data is preserved throughout the component lifecycle using state values.
Let's connect ๐
Catch me here ๐
Hope you all liked the post, share your impressions and queries below ๐