I have the following component where I display user's existing details in the inputs as values and user should be able to change those details and click save. But the issue is that it shows the following error in the console:
**index.js:1 Warning: A component is changing a controlled input of type text to be uncontrolled.**
Here is the component code:
const Settings = (props) => {
const { createUser, isAuthenticated, history, errors } = props;
const dispatch = useDispatch();
const authUser = useSelector(state => state.auth.user);
const [user, setUser] = useState({
data: {
name: "",
email: "",
password: "",
},
});
const [error, setError] = useState({
nameError: "",
emailError: "",
passwordError: "",
});
useEffect(() => {
setUser({
data: {
email:authUser.email,
}
});
}, [authUser]);
const { name, email, password } = user.data;
const { nameError, emailError, passwordError } = error;
const onUpdateUser = (e) => {
e.preventDefault();
const isValid = formValidator(user.data, setError);
if (isValid) {
dispatch(updateUser(user.data))
}
};
const onChange = (e) => {
const { name, value } = e.target;
const { data } = user;
setUser({
data: {
...data,
[name]: value,
},
});
};
return (
<BForm title="Create an account" handleSubmit={onUpdateUser}>
{errors ? <p className="error-feedback">{errors}</p> : ""}
<BInput
name="name"
type="text"
handleChange={onChange}
value={name}
placeholder="Your Name"
error={nameError}
/>
<BInput
name="email"
type="email"
handleChange={onChange}
value={email}
placeholder="Email"
error={emailError}
required
/>
<BInput
name="password"
type="password"
value={password}
handleChange={onChange}
placeholder="Password"
error={passwordError}
required
/>
<div className="buttons">
<BButton customClass="login-btn" isfullwidth={true} type="submit">
{" "}
Save{" "}
</BButton>
</div>
</BForm>
);
};
export default Settings;
What is wrong and how can be it fixed? I need to let see the existing values and then change whatever they want.
useState
doesn't allow patching like setState
did (even if it did, your data is nested at the data
key so it still wouldn't work). The problem is at this line:
useEffect(() => {
setUser({
data: {
email:authUser.email,
}
});
}, [authUser]);
It needs to look like this:
useEffect(() => {
setUser(({data}) => ({
data: {
...data,
email:authUser.email
}
}))
}, [authUser]);
Otherwise, it will remove the name
and password
keys and then the inputs will have undefined
values (eg become uncontrolled).
You problem in useEffect
. Because you only update email so name
and password
will be lost. So the initial value of these input will show this warning. You can update like this:
useEffect(() => {
setUser(preState => ({
data: {
...preState.data,
email:authUser.email,
}
}));
}, [authUser]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.