Home > Software engineering >  How to pass a useState hook to the parent component and update an object?
How to pass a useState hook to the parent component and update an object?

Time:04-15

I have a user component and a InputField component in React. I know my code is wrong, but it should show, what I plan to do. Instead of having multiple useState hooks for each property of the user, I want to update one user object where an Input field can update a specific property of the user object.

const User = () => {
  const [user, setUser] = useState({
    name: "",
    email: "",
  });

  return (
    <>
      <InputField
        name="name"
        value={user.name}
        onChange={() => setUser({ ...user, name: value })}
      />
      <InputField
        name="email"
        value={user.email}
        onChange={() => setUser({ ...user, email: value })}
      />
    </>
  );
};

const InputField = ({ name, value }) => {
  const [value, setValue] = useState("");
  return (
    <input
      type="text"
      id={name}
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
};

I think what I am doing with the value prop is correct, but the onChange is not correct and this is my issue. How can I pass the setValue up to the User component so that it updates the name or the email?

CodePudding user response:

You need to move your onchange logic to the parent component. So you can make an onchange function in the parent and pass that to the input field. Also I would just use the targets name attribute to set the state instead of setting an id on the input. So something like the following:

const InputField = ({ name, value, onChange }) => {
  return (
    <input
      type="text"
      name={name}
      value={value}
      onChange={onChange}
    />
  );
};


const User = () => {
  const [user, setUser] = useState({
    name: "",
    email: "",
  });

  const onChange = (e) => {
    setUser({
      ...user,
      [e.target.name]: e.target.value
    })
  }

  return (
    <>
      <InputField
        name="name"
        value={user.name}
        onChange={onChange}
      />
      <InputField
        name="email"
        value={user.email}
        onChange={onChange}
      />
    </>
  );
}; 

CodePudding user response:

You're not getting onChange from the props in the InputField component.

const InputField = ({ name, value, onChange }) => {
  return (
    <input
      type="text"
      id={name}
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
};

And then you'd need to get the value passed in from the child component:

<InputField
  name="name"
  value={user.name}
  onChange={(value) => setUser({ ...user, name: value })}
/>
<InputField
  name="email"
  value={user.email}
  onChange={(value) => setUser({ ...user, email: value })}
/>

I think this should solve it.

  • Related