Reputation: 1
I am trying to write a contact management application that uses react state to store the contact information.
I have two states, one data and the other userData. The data is supposed to be an object that stores the contact as user enters the contact information while userData would be an array of all the data objects.
But for some reason, I only get one property from the object, It's always the last entered field. I don't know what I am doing wrong. Please help. my code:
const [data, setData] = useState({
firstName: "",
lastName: "",
phoneNumber: "",
address: "",
imag: "",
});
// declear a new state varaible to store data
const [userData, setUserData] = useState([""]);
function handleChange(e) {
let name = e.target.name;
let value = e.target.value;
setData({
[name]: value,
});
}
function handleSubmit(e) {
e.preventDefault();
setUserData([...userData, data]);
}
/*le.log(userData);
}, [userData]);*/
console.log(userData);
return (
<>
<form id="form" className="needs-validation" onSubmit={handleSubmit}>
<div>
<input
className="imgFile"
type="text"
placeholder="First name"
value={data.firstName}
name="firstName"
onChange={handleChange}
/>
<input
className="imgFile"
type="text"
placeholder="Last name"
value={data.lastName}
name="lastName"
onChange={handleChange}
/>
<input
className="imgFile"
type="tel"
placeholder="Phone Number"
value={data.phoneNumber}
name="phoneNumber"
onChange={handleChange}
/>
<input
className="imgFile"
type="email"
placeholder="Email"
value={data.email}
name="email"
onChange={handleChange}
/>
<input
className="imgFile"
type="text"
placeholder="Address"
value={data.address}
name="address"
onChange={handleChange}
/>
<input
type="file"
name="img"
accept="image/*"
value={data.img}
onChange={handleChange}
/>
<button className="contactButton">Save </button>
</div>
</form>
</>
);
}
Upvotes: 0
Views: 803
Reputation: 84
I have pasted the correct code here , using spread operator the copy of previous data is provided when setData is called so that it's values are not overwritten.
const [data, setData] = useState({
firstName: "",
lastName: "",
phoneNumber: "",
address: "",
imag: "",
});
// declear a new state varaible to store data
const [userData, setUserData] = useState([""]);
function handleChange(e) {
let name = e.target.name;
let value = e.target.value;
setData({
...data,
[name]: value,
});
}
function handleSubmit(e) {
e.preventDefault();
setUserData([...userData, data]);
}
console.log(userData);
return (
<>
<form id="form" className="needs-validation" onSubmit={handleSubmit}>
<div>
<input
className="imgFile"
type="text"
placeholder="First name"
value={data.firstName}
name="firstName"
onChange={handleChange}
/>
<input
className="imgFile"
type="text"
placeholder="Last name"
value={data.lastName}
name="lastName"
onChange={handleChange}
/>
<input
className="imgFile"
type="tel"
placeholder="Phone Number"
value={data.phoneNumber}
name="phoneNumber"
onChange={handleChange}
/>
<input
className="imgFile"
type="email"
placeholder="Email"
value={data.email}
name="email"
onChange={handleChange}
/>
<input
className="imgFile"
type="text"
placeholder="Address"
value={data.address}
name="address"
onChange={handleChange}
/>
<input
type="file"
name="img"
accept="image/*"
value={data.img}
onChange={handleChange}
/>
<button className="contactButton">Save </button>
</div>
</form>
</>
);
}
Upvotes: 1
Reputation: 2104
So your code is good , the problem is when you use setData
you lose everything. In functional components you need to spread the oldData
and then change what you like.
Your setData
should look like this inside handleChange
:
setData(oldData => ({
...oldData,
[name]: value,
}));
Than in your submit form, you don't need at all userData
, because you can just use the data
object which has all the information you need.
And you can change your handleSubmit
like this:
function handleSubmit(e) {
e.preventDefault();
console.log('data',data);
// do whatever with your "data", the object has all the information inside
}
Upvotes: 0
Reputation: 1736
You are forgetting to spread -data when you are doing this:
setData({
[name]: value,
});
should be this instead:
setData({
...data
[name]: value,
});
Upvotes: 0