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?
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.
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}
/>
</>
);
};