Реакция тега ввода отключена - PullRequest
1 голос
/ 08 апреля 2020

Я пытаюсь создать форму входа в React. js. Я хочу включить / отключить кнопку входа в систему на основе результатов, возвращаемых методом проверки. React выдает ошибку 'Недопустимое значение для метки disabled в теге. Либо удалите его из элемента, либо передайте строковое или числовое значение, чтобы сохранить его в DOM. '. Кто-нибудь сталкивался с такой же ошибкой? Помогите мне понять, что здесь происходит не так?

import React, { Component } from "react";
import Input from "../common/input";
import Joi from "joi-browser";

class LoginForm extends Component {
  state = {
    account: {
      username: "",
      password: "",
    },
    errors: {},
  };

  schema = {
    username: Joi.string().required().label("Username"),
    password: Joi.string().required().label("Password"),
  };

  abortEarly = {
    abortEarly: false,
  };

  handleSubmit = (event) => {
    event.preventDefault();
    const errors = this.validate();
    if (errors) return;
    console.log("submitted");
  };

  validate = () => {
    const result = Joi.validate(
      this.state.account,
      this.schema,
      this.abortEarly
    );
    const errors = {};
    if (!result.error) return null;
    result.error.details.map((detail) => {
      errors[detail.path[0]] = detail.message;
      return detail.path[0];
    });
    // console.log(errors);
    this.setState({ errors });
    return errors;
  };

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

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

  render() {
    const { account, errors } = this.state;
    return (
      <div>
        <h1>Login</h1>
        <form onSubmit={this.handleSubmit}>
          <Input
            label="Username"
            name="username"
            value={account.username}
            onChange={this.handleChange}
            error={errors.username}
          ></Input>
          <Input
            label="Password"
            name="password"
            value={account.password}
            onChange={this.handleChange}
            error={errors.password}
          ></Input>

          <button disabled={this.validate} className="btn btn-primary">
            Login
          </button>
        </form>
      </div>
    );
  }
}

export default LoginForm;

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

Disabled - логическое свойство, означающее, что оно может иметь только значение true или false. Вместо логического значения ваша функция validate возвращает объект, поэтому React выдает ошибку «Invalid value». Чтобы это исправить, вы можете проверить, является ли результат this.validate нулевым:

<button 
    disabled={(this.validate() !== null)} 
    className="btn btn-primary"
>
    Login
</button>

Кроме того, вы вообще забыли назвать свой this.validate :)

Относительно " Максимальная глубина обновления ... ", вы должны удалить this.setState из this.validate, потому что вы уже помещаете ошибку в состояние в методе handleChange.

0 голосов
/ 08 апреля 2020

Вот вам go с решением

import React, { Component } from "react";
import Input from "../common/input";
import Joi from "joi-browser";

class LoginForm extends Component {
  state = {
    account: {
      username: "",
      password: "",
    },
    errors: {},
  };

  schema = {
    username: Joi.string().required().label("Username"),
    password: Joi.string().required().label("Password"),
  };

  abortEarly = {
    abortEarly: false,
  };

  handleSubmit = (event) => {
    event.preventDefault();
    const errors = this.validate();
    if (errors) return;
    console.log("submitted");
  };

  validate = () => {
    const result = Joi.validate(
      this.state.account,
      this.schema,
      this.abortEarly
    );
    const errors = {};
    if (!result.error) return false;
    result.error.details.map((detail) => {
      errors[detail.path[0]] = detail.message;
      return detail.path[0];
    });
    // console.log(errors);
    this.setState({ errors });
    return true;
  };

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

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

  render() {
    const { account, errors } = this.state;
    return (
      <div>
        <h1>Login</h1>
        <form onSubmit={this.handleSubmit}>
          <Input
            label="Username"
            name="username"
            value={account.username}
            onChange={this.handleChange}
            error={errors.username}
          ></Input>
          <Input
            label="Password"
            name="password"
            value={account.password}
            onChange={this.handleChange}
            error={errors.password}
          ></Input>

          <button disabled={this.validate} className="btn btn-primary">
            Login
          </button>
        </form>
      </div>
    );
  }
}

export default LoginForm;

validate метод должен возвращать логическое значение (true или false)

...