Reputation: 15
Originally, I designed this component to have a useState for each individual input. After realizing that this would not be the best approach for adding new inputs, I refactored to use only one useState. I'm able to get the values for all, but gender. I'm hoping someone could point me in the right direction.
Note: I realize it's not picking up the value because I'm not using person.gender. I went ahead and tried to add value={person.gender = "the value I want"} for each input.
const Forms = () => {
const [person, setPerson] = useState({
firstName: "",
lastName: "",
age: "",
gender: "",
email: "",
});
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.lastName && person.age && person.email) {
const newPerson = {
...person,
id: new Date().getTime().toString(),
};
setPeople([...people, newPerson]);
setPerson({
firstName: "",
lastName: "",
age: "",
gender: "",
email: "",
});
}
};
console.log(person.gender);
return (
<article>
<h2>Forms</h2>
<form className="form">
<div className="form-control">
<label htmlFor="firstName">First Name:</label>
<input
type="text"
id="firstName"
name="firstName"
value={person.firstName}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="lastName">Last Name:</label>
<input
type="text"
id="LastName"
name="lastName"
value={person.lastName}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="age">Age:</label>
<input
type="text"
id="age"
name="age"
value={person.age}
onChange={handleChange}
/>
</div>
<div className="form-control">
<label htmlFor="gender">Gender:</label>
<select onChange={handleChange} id="gender">
<option name="gender" value="male">
Male
</option>
<option name="gender" value="female">
Female
</option>
<option name="gender" value="prefer not to answer">
prefer not to answer
</option>
</select>
</div>
<div className="form-control">
<label htmlFor="email">Email:</label>
<input
type="email"
id="email"
name="email"
value={person.email}
onChange={handleChange}
/>
</div>
<button type="submit" className="btn" onClick={handleSubmit}>
Submit
</button>
</form>
{people.map((person) => {
const { firstName, lastName, age, gender, email, id } = person;
return (
<div className="item" key={id}>
<h4>
{firstName} {lastName}
</h4>
<span>{age}</span>
<span>{gender}</span>
<p>{email}</p>
</div>
);
})}
</article>
);
};
export default Forms;
Thanks, Sean
Upvotes: 0
Views: 43
Reputation: 93
Try reading documentation in react about forms
https://reactjs.org/docs/forms.html
Another thing I think it e.target.value is not working in select form, also you shoud use independent state for every form input because in this layer you cause some effect and rerender
Upvotes: 0
Reputation: 10652
You have to give the name attribute to the select element, not to its options
<select name="gender" onChange={handleChange} id="gender">
Upvotes: 1