最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Input validation if empty or number - Stack Overflow

programmeradmin4浏览0评论

I've created this method that gets the state of the calculator input and checks if its empty or not. I need help with two things:

  • What's the cleanest way to add here a validation to check if each input is also a number and outputs and error "Input must be a number"
  • Currently I have one error message that fires whether all the inputs are present or not, where what I want is for it to validate each input separately and fire an error under each one. How do I do it but still keep this function concise?

           constructor(props) {
            super(props);
            this.state = {
                price: 0,
                downP: 0,
                term: 0,
                interest: 0,
                error: ''
            };
        }
    
     handleValidation = () => {
                    const {
                        price,
                        downP,
                        loan,
                        interest,
                    } = this.state;
                    let error = '';
                    let formIsValid = true;
                        if(!price || 
                            !downP ||
                            !loan ||
                            !interest){
                            formIsValid = false;
                            error = "Input fields cannot be empty";
                        } 
    
           this.setState({error: error});
          return formIsValid;
        }
    

    And then this is the error message

         <span style={{color: "red"}}>{this.state.error}</span>
    

I've created this method that gets the state of the calculator input and checks if its empty or not. I need help with two things:

  • What's the cleanest way to add here a validation to check if each input is also a number and outputs and error "Input must be a number"
  • Currently I have one error message that fires whether all the inputs are present or not, where what I want is for it to validate each input separately and fire an error under each one. How do I do it but still keep this function concise?

           constructor(props) {
            super(props);
            this.state = {
                price: 0,
                downP: 0,
                term: 0,
                interest: 0,
                error: ''
            };
        }
    
     handleValidation = () => {
                    const {
                        price,
                        downP,
                        loan,
                        interest,
                    } = this.state;
                    let error = '';
                    let formIsValid = true;
                        if(!price || 
                            !downP ||
                            !loan ||
                            !interest){
                            formIsValid = false;
                            error = "Input fields cannot be empty";
                        } 
    
           this.setState({error: error});
          return formIsValid;
        }
    

    And then this is the error message

         <span style={{color: "red"}}>{this.state.error}</span>
    
Share Improve this question asked Jan 30, 2019 at 22:21 Max TMax T 1,4554 gold badges25 silver badges40 bronze badges 2
  • 1 Do yourself a favor and look into Formik and Yup for form handling and validation... jaredpalmer./formik – SakoBu Commented Jan 30, 2019 at 22:25
  • Abd if not then here is a tutorial for you: learnetto./blog/how-to-do-simple-form-validation-in-reactjs – SakoBu Commented Jan 30, 2019 at 22:27
Add a ment  | 

4 Answers 4

Reset to default 8

If you want to keep your error messages separate I would remend to reorganize your state.

So scalable solution (you may add more controls by just adding them to state) may look like:

class NumberControlsWithErrorMessage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputs: [
        { name: 'price', value: 0, error: ''},
        { name: 'downP', value: 0, error: '' },
        { name: 'term', value: 0, error: '' },
        { name: 'interest', value: 0, error: '' }
      ]
    };
  }

  handleInputChange = (idx, event) => {
    const target = event.target;
    const name = target.name;
    let error = '';

    if (isNaN(target.value)) {
      error = `${name} field can only be number`
    }

    if (!target.value) {
      error = `${name} field cannot be empty`
    }

    this.state.inputs[idx] = {
      ...this.state.inputs[idx],
       value: target.value,
      error
    }

    this.setState({
      inputs: [...this.state.inputs]
    });
  }

  render() {
    return (
      <form>
        {this.state.inputs.map((input, idx) => (
          <div>
          <label htmlFor="">{input.name}</label>
          <input type="text" value={input.value} onChange={(e) => this.handleInputChange(idx, e)}/>
          {input.error && <span>{input.error}</span> }
          </div>
        ))}
      </form>
    );
  }
}

Working example

Also if you are building a plex form, you may want to try some React solution for forms, where all the mechanism for listening to events, state updates, validatoin are already handled for you. Like reactive-mobx-form

A straightforward way of handling multiple objects needing validation is to store an errors object in your state that has a property for each input field. Then you conditionally render the error underneath each input field depending on whether or not it has an error. Here is a very basic example:

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      price: 0, downP: 0, term: 0, interest: 0,
      errors: { price: '', downP: '', term: '', interest: '' }
    };
  }

  handleValidation = () => {
    const { price, downP, loan, interest } = this.state;
    let errors = { price: '', downP: '', term: '', interest: '' };

    if (!price) {
     errors.price = 'Price is required';
    } else if (isNaN(price)) {
      errors.price = 'Price must be a number';
    }

    if (!downP) {
      errors.downP = 'Down Payment is required';
    }

    // Rest of validation conditions go here...

    this.setState({ errors });
  }

  render() {
    const { errors } = this.state;

    return (
      <form>
        <input name="price" value={this.state.price} onChange={this.handleChange} />
        {errors.price != '' && <span style={{color: "red"}}>{this.state.errors.price}</span>}
        <input name="downP" value={this.state.downP} onChange={this.handleChange} />
        {errors.downP != '' && <span style={{color: "red"}}>{this.state.errors.downP}</span>}

        {/** Rest of ponents go here */}
      </form>
    );
  }
}

You can choose whether or not to run validation once the form submits or on every keypress and that will affect how when those messages appear and disappear, but this should give you an idea on how you would manage error messages specific to each input field.

You can do this:

  handleValidation() {
      const { price, downP,loan, interest} = this.state;

      // only each block with generate error
      if (!price || isNaN(price)) {
        this.setState({ error: 'price is not valid' });
      } else if (!downP || isNaN(downP)) {
        this.setState({ error: 'downP is not valid' });
      } else {
        this.setState({error: ""})
        // submit code here
      }
  }

Note: you dont need to return anything. It will update the error state and only submit the form if it goes into no error (else{}) part

and for render() part add this:

{(this.state.error !== '')
      ? <span style={{color: "red"}}>{this.state.error}</span>
      : ''
}

If you want validation msg on each add errPrice, errDownP and so on to the state, and check for them in render like (this.state.errPrice!== '') {} and so on.

One solution assuming you want a one size fits all error message only checking if it was a number or not would be to put them into an array and set error if the input is not a number.

const inputs = [ price, downP, loan, interest ]

inputs.map(input => {
  if (!input || isNaN(input)){
    error = "Input must be a number"
    formIsValid = false
  }
}

this.setState({error}) 

Something like that maybe.

发布评论

评论列表(0)

  1. 暂无评论