在 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);