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.