反应输入标签禁用道具问题

React input tag disabled prop issue

I am trying to build a login form in React.js. I want to enable/disable Login button based on results return by validate method. React throws error 'Invalid value for prop disabled on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM.'. Does anyone have came across same error? Help me to understand what is going wrong here?

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;

给你一个解决方案

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 方法应该 return 布尔值(真或假)

Disabled 是一个布尔值 属性,这意味着它的值只能是 true 或 false。您的验证函数返回的不是布尔值,而是一个对象,因此 React 会抛出 "Invalid value" 错误。为了解决这个问题,您可以检查 this.validate 的结果是否为空:

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

另外,你根本忘了给你的 this.validate 打电话 :)

关于 "Maximum update depth...",您应该从 this.validate 中删除 this.setState,因为您已经将错误置于 handleChange 方法中。