在 onchange 之后,将密码与 react hooks 匹配不起作用
matching passwords with react hooks is not working after onchange
我正在尝试在两个密码状态相等后更改错误状态。但是当我输入完密码后,onchange 并没有执行,它需要再执行一次。
*关于使用 onkeyup 事件它有效,但我不知道它是否是一个好习惯。
我也试过让它成为一个超时功能,但它也没有帮助
这是我的函数。
const [password, setPassword] = useState('')
const [password2, setPassword2] = useState('')
const [passError, setPerror] = useState(false)
const handleChange = (event) => {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log(name +" "+ value);
if(name == 'username') setUsername(value);
if(name == 'email') setEmail(value);
if(name == 'pass') setPassword(value);
if(name == 'pass2') setPassword2(value);
setTimeout(()=>checkPass(), 2000);
}
const checkPass = () => {
if (password != password2) setPerror(true);
else setPerror(false);
console.log(passError)
}
这是我的 html.
<input type="password" className="form-control" name="pass" placeholder="Password" required=""
value={password} onChange={handleChange} onKeyUp={handleChange} style={{marginBottom: 0}} />
<input type="password" className="form-control" name="pass2" placeholder="Confirm Password" required=""
value={password2} onChange={handleChange} />
{ passError && <p className='alert-danger'>Password does not match!</p>}
问题
这里的问题是您试图引用尚未更新的状态。实际上,您设置的超时时间有多长并不重要,checkPass
的“实例”与未更新状态是在回调范围内排队和关闭的。它将永远永远是 回调被排队时的状态值。
解决方案
不是在更新后使用超时来检查状态,而是使用依赖于密码状态值的 useEffect
挂钩来调用 checkPass
并进行验证。类似地,将 passError
状态的日志记录移动到 useEffect
挂钩。
useEffect(() => {
checkPass();
}, [password, password2]);
useEffect(() => {
console.log(passError);
}, [passError]);
const handleChange = (event) => {
const { checked, name, type, value } = event.target;
const newValue = type === 'checkbox' ? checked : value;
if (name === 'username') setUsername(newValue);
if (name === 'email') setEmail(newValue);
if (name === 'pass') setPassword(newValue);
if (name === 'pass2') setPassword2(newValue);
}
const checkPass = () => setPerror(password !== password2);
我正在尝试在两个密码状态相等后更改错误状态。但是当我输入完密码后,onchange 并没有执行,它需要再执行一次。
*关于使用 onkeyup 事件它有效,但我不知道它是否是一个好习惯。 我也试过让它成为一个超时功能,但它也没有帮助
这是我的函数。
const [password, setPassword] = useState('')
const [password2, setPassword2] = useState('')
const [passError, setPerror] = useState(false)
const handleChange = (event) => {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log(name +" "+ value);
if(name == 'username') setUsername(value);
if(name == 'email') setEmail(value);
if(name == 'pass') setPassword(value);
if(name == 'pass2') setPassword2(value);
setTimeout(()=>checkPass(), 2000);
}
const checkPass = () => {
if (password != password2) setPerror(true);
else setPerror(false);
console.log(passError)
}
这是我的 html.
<input type="password" className="form-control" name="pass" placeholder="Password" required=""
value={password} onChange={handleChange} onKeyUp={handleChange} style={{marginBottom: 0}} />
<input type="password" className="form-control" name="pass2" placeholder="Confirm Password" required=""
value={password2} onChange={handleChange} />
{ passError && <p className='alert-danger'>Password does not match!</p>}
问题
这里的问题是您试图引用尚未更新的状态。实际上,您设置的超时时间有多长并不重要,checkPass
的“实例”与未更新状态是在回调范围内排队和关闭的。它将永远永远是 回调被排队时的状态值。
解决方案
不是在更新后使用超时来检查状态,而是使用依赖于密码状态值的 useEffect
挂钩来调用 checkPass
并进行验证。类似地,将 passError
状态的日志记录移动到 useEffect
挂钩。
useEffect(() => {
checkPass();
}, [password, password2]);
useEffect(() => {
console.log(passError);
}, [passError]);
const handleChange = (event) => {
const { checked, name, type, value } = event.target;
const newValue = type === 'checkbox' ? checked : value;
if (name === 'username') setUsername(newValue);
if (name === 'email') setEmail(newValue);
if (name === 'pass') setPassword(newValue);
if (name === 'pass2') setPassword2(newValue);
}
const checkPass = () => setPerror(password !== password2);