I have this basic Login
component with email and password fields that use a two-way binding approach. The issue I'm facing is that my state is not updated when the onChange
event triggers on either inputs. What is causing this?
import { useState } from "react";
export default function Login() {
const [ enteredValues, setEnteredValues ] = useState({
email: {
value: '',
didEdit: false
},
password: {
value: '',
didEdit: false
}
})
function handleSubmit(event) {
event.preventDefault()
console.log(`User email: ${enteredValues.email.value}`)
console.log(`User password: ${enteredValues.password.value}`)
}
function handleInputChange(identifier, value) {
console.log(`Changing ${identifier} to ${value}`);
setEnteredValues(prevValues => ({
...prevValues,
[identifier]: {
value: value,
...prevValues[identifier]
}
}))
}
function handleInputBlur(identifier) {
setEnteredValues(prevValues => ({
...prevValues,
[identifier]: {
...prevValues[identifier],
didEdit: true
}
}))
}
return (
<form onSubmit={ handleSubmit }>
<h2>Login</h2>
<div className="control-row">
<div className="control no-margin">
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
name="email"
onBlur={ () => handleInputBlur('email') }
onChange={(event) => handleInputChange('email', event.target.value)}
value={enteredValues.email.value}
/>
</div>
<div className="control no-margin">
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
name="password"
onChange={(event) => handleInputChange('password', event.target.value)}
value={enteredValues.password.value}
/>
</div>
</div>
<p className="form-actions">
<button className="button button-flat">Reset</button>
<button className="button">Login</button>
</p>
</form>
);
}
You're resetting your state immediately after updating it:
setEnteredValues(prevValues => ({
...prevValues,
[identifier]: {
value: value,
...prevValues[identifier] // This is overwriting the value change above
}
}))
Reverse those two lines for:
setEnteredValues(prevValues => ({
...prevValues,
[identifier]: {
...prevValues[identifier],
value: value,
}
}))