Javascript 如何使用TS React中的Joi验证两个密码字段?
我正在用TypeScript构建一个可重用的表单组件,现在我们称它为Javascript 如何使用TS React中的Joi验证两个密码字段?,javascript,reactjs,typescript,joi,Javascript,Reactjs,Typescript,Joi,我正在用TypeScript构建一个可重用的表单组件,现在我们称它为AbstractForm。它被设计为被其他组件继承,比如LoginForm,RegisterForm等等,假设我正在开发一些DerivedForm组件。验证我正在使用的字段Joi。派生组件只需提供域模型(Joi验证模式)和submit方法 除了我想使用两个密码字段外,其他一切都非常有效,并且通过Joi.string().valid(this.state.data.password)检查第二个密码是否与第一个密码匹配。即使两个密码
AbstractForm
。它被设计为被其他组件继承,比如LoginForm
,RegisterForm
等等,假设我正在开发一些DerivedForm
组件。验证我正在使用的字段Joi
。派生组件只需提供域模型(Joi验证模式)和submit方法除了我想使用两个密码字段外,其他一切都非常有效,并且通过
Joi.string().valid(this.state.data.password)
检查第二个密码是否与第一个密码匹配。即使两个密码完全相同,Joi也不会通过验证。Joi仍然会抛出一个错误,表示它们不相同。我甚至想不出原因。有人能提出这种行为的原因吗?我没有使用
Joi.ref('password')
,因为字段是与每个onChange
事件隔离验证的(方法validateProperty()
在AbstractForm
中执行)这是
AbstractForm
模块中定义的模式接口:
export interface Schema {
[key: string]: Joi.Schema;
}
这是我在派生表单
中的模式:
schema: Schema = {
name: Joi.string()
.required()
.min(1)
.label('Name'),
email: Joi.string()
.required()
.email()
.min(5)
.label('Email'),
password: Joi.string()
.required()
.min(8)
.label('Password')
.error(
errors => 'Passwords should match and have at least 8 characters.'
),
repeatPassword: Joi.string()
.valid(this.state.data.password)
.required()
.label('Password')
.error(
errors => 'Passwords should match and have at least 8 characters.'
),
};
validateProperty = (name: string, value: string) => {
const property = { [name]: value };
const propSchema: Schema = { [name]: this.schema[name] };
const { error } = Joi.validate(property, propSchema);
return error ? error.details[0].message : null;
};
handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
const data = { ...this.state.data };
data[name] = value;
const errors = { ...this.state.errors };
const errorMessage = this.validateProperty(name, value);
if (errorMessage) errors[name] = errorMessage;
else delete errors[name];
this.setState({ data, errors });
};
这就是在抽象表单中验证这些字段的方式:
schema: Schema = {
name: Joi.string()
.required()
.min(1)
.label('Name'),
email: Joi.string()
.required()
.email()
.min(5)
.label('Email'),
password: Joi.string()
.required()
.min(8)
.label('Password')
.error(
errors => 'Passwords should match and have at least 8 characters.'
),
repeatPassword: Joi.string()
.valid(this.state.data.password)
.required()
.label('Password')
.error(
errors => 'Passwords should match and have at least 8 characters.'
),
};
validateProperty = (name: string, value: string) => {
const property = { [name]: value };
const propSchema: Schema = { [name]: this.schema[name] };
const { error } = Joi.validate(property, propSchema);
return error ? error.details[0].message : null;
};
handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
const data = { ...this.state.data };
data[name] = value;
const errors = { ...this.state.errors };
const errorMessage = this.validateProperty(name, value);
if (errorMessage) errors[name] = errorMessage;
else delete errors[name];
this.setState({ data, errors });
};
validateProperty=(名称:string,值:string)=>{
常量属性={[name]:值};
const-propSchema:Schema={[name]:this.Schema[name]};
const{error}=Joi.validate(属性,propSchema);
返回错误?错误。详细信息[0]。消息:null;
};
handleChange=(e:ChangeEvent)=>{
const{name,value}=e.currentTarget;
const data={…this.state.data};
数据[名称]=值;
常量错误={…this.state.errors};
const errorMessage=this.validateProperty(名称、值);
如果(errorMessage)errors[名称]=errorMessage;
否则删除错误[名称];
this.setState({data,errors});
};
我还知道this.setState()
以及新的useState()
调用都是异步的,但是我们在这里讨论的是针对不同的字段进行验证,所以这应该不是问题
如果需要,我可以为这两个模块添加所有代码。提前谢谢 事实证明,只有在安装组件时才会生成对第一个密码字段的有效引用。要更新引用,可以添加以下代码:
componentDidUpdate() {
this.schema.repeatPassword = Joi.string()
.min(8)
.valid(this.state.data.password)
.required()
.label('Password')
.error(
errors => 'Passwords should match and have at least 8 characters.'
);
}
…这样它就可以记住新的“有效”值。我认为这是因为我使用的是类组件,而不是函数组件。使用功能组件,模式将自动更新每个渲染