【问题标题】:Password matching validation using the Joi schema in React not working在 React 中使用 Joi 模式的密码匹配验证不起作用
【发布时间】:2021-08-31 04:36:53
【问题描述】:

我想在 React 中创建一个密码更改表单。这是我的组件的代码:

import React, { Component } from "react";
import Joi from "joi-browser";
import "./Login/Login.css";
import { UAA } from "../../Actions/Types";

class ChangePassword extends Component {
  state = {
    account: {
      currentPassword: "",
      newPassword: "",
      newPasswordRepeated: "",
    },
    errors: {},
    auth: UAA,
  };

  schema = {
    currentPassword: Joi.string().required().label("Password"),
    newPassword: Joi.string().min(12).max(64).required().label("Password"),
    newPasswordRepeated: Joi.any().valid(Joi.ref("newPassword")).required(),
  };

  validate = () => {
    const options = { abortEarly: false };
    const { error } = Joi.validate(this.state.account, this.schema, options);
    if (!error) return null;
    const errors = {};
    for (let item of error.details) {
      errors[item.path[0]] = item.message;
    }
    return errors;
  };

  validateProperty = ({ name, value }) => {
    const obj = { [name]: value };
    console.log(obj);
    const schema = { [name]: this.schema[name] };
    console.log(schema);
    const { error } = Joi.validate(obj, schema);
    console.log(JSON.stringify(error));
    return error ? error.details[0].message : null;
  };

  handleSubmit = (e) => {
    e.preventDefault();
    const errors = this.validate();
    this.setState({ errors: errors || {} });
    if (errors) return;
    //todo : call server
  };

  handleChange = ({ currentTarget: input }) => {
    const errors = { ...this.state.errors };
    const errorMessage = this.validateProperty(input);
    if (errorMessage) errors[input.name] = errorMessage;
    else delete errors[input.name];
    const account = { ...this.state.account };
    account[input.name] = input.value;
    this.setState({
      account: account,
      errors: errors,
    });
  };

  render() {
    const { errors, account } = this.state;
    return (
      <div className="container">
        <div className="col-md-5 offset-md-3">
          <form
            className="login-form"
            onSubmit={(event) => this.handleSubmit(event)}
          >
            <p />
            <p className="form-label">Current password</p>
            <input
              type="password"
              id="currentPassword"
              name="currentPassword"
              value={account.currentPassword}
              onChange={this.handleChange}
            />
            {errors.currentPassword && (
              <div className="alert alert-danger">{errors.currentPassword}</div>
            )}
            <p className="form-label">New password</p>
            <input
              type="password"
              name="newPassword"
              onChange={this.handleChange}
              value={account.newPassword}
            />
            {errors.newPassword && (
              <div className="alert alert-danger">{errors.newPassword}</div>
            )}
            <p className="form-label">Confirm password</p>
            <input
              type="password"
              name="newPasswordRepeated"
              value={account.newPasswordRepeated}
              onChange={this.handleChange}
            />
            {errors.newPasswordRepeated && (
              <div className="alert alert-danger">
                {errors.newPasswordRepeated}
              </div>
            )}
            <div className="submit-login-form">
              <input
                type="submit"
                value="Submit"
                disabled={this.validate()}
              ></input>
            </div>
          </form>
        </div>
      </div>
    );
  }
}

export default ChangePassword;

当用户输入重复密码时,我想验证该重复密码是否与已输入的新密码匹配。这是在validateProperty 方法中完成的。问题是即使两个密码匹配,Joi 也会返回验证错误。我很感激这方面的任何帮助。

【问题讨论】:

    标签: javascript reactjs joi


    【解决方案1】:

    经过一番研究,我能够找出问题所在。 问题在于方法validateProperty,特别是在验证字段newPasswordRepeated 时使用的Joi 模式中。在此架构中,需要为newPassword 添加验证规则。因此我改变了我的validateProperty 方法,如下所示:

    validateProperty = ({ name, value }) => {
        if (name === "newPasswordRepeated") {
          const { account } = this.state;
          const obj = { newPassword: account.newPassword, [name]: value };
          const schema = {
            [name]: this.schema[name],
            newPassword: this.schema["newPassword"],
          };
          const { error } = Joi.validate(obj, schema);
          return error ? error.details[0].message : null;
        } else {
          const obj = { [name]: value };
          const schema = { [name]: this.schema[name] };
          const { error } = Joi.validate(obj, schema);
          return error ? error.details[0].message : null;
        }
      };
    

    希望有人觉得这很有用。

    【讨论】:

    • 这对我有用
    猜你喜欢
    • 2017-10-03
    • 2018-10-16
    • 2020-12-23
    • 2019-05-04
    • 2019-05-28
    • 2021-05-22
    • 2020-06-10
    • 1970-01-01
    • 2021-06-04
    相关资源
    最近更新 更多