wealthmiq
wealthmiq

Reputation: 1

How to update state with input values

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

Answers (3)

asfandyar24
asfandyar24

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

CevaComic
CevaComic

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

Talmacel Marian Silviu
Talmacel Marian Silviu

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

Related Questions