我如何确认与Yup验证的React表单中的匹配值?



我正在尝试用yup验证确认密码值。我看过的每个解决方案都指向同一行代码,但它没有按预期工作。

我有一个有两个输入(密码和确认)和一个提交按钮的表单。在formValues状态通过验证之前,提交按钮将被禁用。当密码不匹配时,提交按钮被正确地禁用,当密码匹配时,按钮变为活动状态。但是错误信息并没有消失。

这是我的yup模式:

import * as yup from 'yup'
export default yup.object().shape({
password: yup
.string()
.required("Password required"),
confirm: yup
.string()
.oneOf([yup.ref("password"), null], "Passwords don't match")
})

,下面是表单本身的代码:

const initialValue = {
password: "",
confirm: ""
}
export default function Form() {
const [formValues, setFormValues] = useState(initialValue)
const [formErrors, setFormErrors] = useState(initialValue)
const [disabled, setDisabled] = useState(true)
const onChange = (e) => {
const {name, value} = e.target;
yup
.reach(formSchema, name)
.validate(value)
.then(() => {
setFormErrors({ ...formErrors, [name]: '' })
})
.catch((err) => {
setFormErrors({ ...formErrors, [name]: err.errors[0] })
})

setFormValues({...formValues, [name]: value })
}
const onSubmit = (e) => {
e.preventDefault()
}
useEffect(() => {
formSchema.isValid(formValues).then((valid) =>
setDisabled(!valid))
}, [formValues])
return (
<div>
<form onSubmit={onSubmit}>
<label>
Password:
<input
type="text"
name="password"
onChange={onChange}
value={formValues.password}
/>
</label>
<label>
Confirm Password:
<input
type="text"
name="confirm"
onChange={onChange}
value={formValues.confirm}
/>
</label>
<button type="submit" disabled={disabled}>
Submit
</button>
<div className="errors">
<div>{formErrors.password}</div>
<div>{formErrors.confirm}</div>
</div>
</form>
</div>
)
}

我在第二个密码参数的末尾添加了required(),它可以工作。

confirm: yup.string().oneOf([yup.ref("password"), null], "Passwords don't match") }).required()

首先,每次检查旧的formValues。其次,您应该检查触摸字段显示错误消息后,用户影响他们。我建议使用Formik

但是我修改了你的代码,你也可以在这里检查

import React, { useState, useEffect } from "react";
import * as yup from "yup";
const initialValue = {
password: "",
confirm: ""
};
export default function Form() {
const [formValues, setFormValues] = useState(initialValue);
const [formErrors, setFormErrors] = useState(initialValue);
const [touched, setTouched] = useState({password: false, confirm: false});
const [disabled, setDisabled] = useState(true);
const formSchema = yup.object().shape({
password: yup.string().required("Password required"),
confirm: yup
.string()
.oneOf([yup.ref("password"), null], "Passwords don't match")
});
const onChange = (e) => {
const { name, value } = e.target;
setFormValues({ ...formValues, [name]: value });
setTouched({...touched, [name]: true});
};
const onSubmit = (e) => {
e.preventDefault();
};
useEffect(() => {
yup
.reach(formSchema)
.validate(formValues, { abortEarly: false })
.then(() => {
setFormErrors({});
})
.catch((err) => {
const errors = {};
err.inner.forEach(error => {
if(touched[error.path]) errors[error.path] = error.message;
})
setFormErrors(errors);
});
formSchema.isValid(formValues).then(valid => setDisabled(!valid));
}, [formValues]);
return (
<div>
<form onSubmit={onSubmit}>
<label>
Password:
<input
type="text"
name="password"
onChange={onChange}
value={formValues.password}
/>
</label>
<label>
Confirm Password:
<input
type="text"
name="confirm"
onChange={onChange}
value={formValues.confirm}
/>
</label>
<button type="submit" disabled={disabled}>
Submit
</button>
<div className="errors">
<div>{touched.password && formErrors.password}</div>
<div>{touched.confirm && formErrors.confirm}</div>
</div>
</form>
</div>
);
}

changepassword: Yup.string().oneOf([Yup.ref('password')], 'Passwords must match').required('changepassword is required')

最新更新