繁体   English   中英

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

[英]How to validate two password fields with Joi in TS React?

我正在用 TypeScript 构建一个可重用的表单组件,现在我们称之为AbstractForm 它被设计为由其他组件(如LoginFormRegisterForm等)继承,假设我正在处理一些DerivedForm组件。 为了验证我使用的字段Joi 派生组件只需要提供域模型(Joi 验证模式)和提交方法。
一切都运行良好并且验证完美,除非我想使用两个密码字段,并且通过Joi.string().valid(this.state.data.password)检查第二个密码以匹配第一个密码。 即使两个密码相同,它也永远不会通过验证,Joi 仍然抛出一个错误,说它们不是。 我什至想不出原因。 有人可以建议这种行为的原因是什么?
我没有使用Joi.ref('password')而是因为字段是通过每个onChange事件Joi.ref('password') validateProperty() AbstractForm中的validateProperty()方法是这样做的)。

这是AbstractForm模块中定义的 Schema 接口:

export interface Schema {
  [key: string]: Joi.Schema;
}

这是我在DerivedForm中的DerivedForm

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.'
  ),
};

这就是在AbstractForm中验证这些字段的方式:

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

我也知道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.'
      );
  }

...所以它可以记住新的“有效”值。 我认为这是因为我使用的是类组件,而不是功能组件。 对于功能组件,架构将自行更新每个渲染。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM