Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用TS React中的Joi验证两个密码字段?_Javascript_Reactjs_Typescript_Joi - Fatal编程技术网

Javascript 如何使用TS React中的Joi验证两个密码字段?

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)检查第二个密码是否与第一个密码匹配。即使两个密码

我正在用TypeScript构建一个可重用的表单组件,现在我们称它为
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.'
      );
  }

…这样它就可以记住新的“有效”值。我认为这是因为我使用的是类组件,而不是函数组件。使用功能组件,模式将自动更新每个渲染