2
\$\begingroup\$

I need to validate multiple input fields using React. I am using a simple if-else block for each input field but I would like to optimize my code and make it better. I feel there can be a better way to validate multiple input fields.

 validateForm = () => {
 const {
 firstName, lastName, mobileNo, city, empType, salary
 } = this.state;
 if (firstName !== '') {
 this.setState({
 firstNameMsg: '',
 validFirstName: false
 });
 } else {
 this.setState({
 firstNameMsg: 'Please enter a vaild first name.',
 validFirstName: true
 });
 }
 if (lastName !== '') {
 this.setState({
 lastNameMsg: '',
 validLastName: false
 });
 } else {
 this.setState({
 lastNameMsg: 'Please enter a vaild last name.',
 validLastName: true
 });
 }
 if (mobileNo.match(/^(\+\d{1,3}[- ]?)?\d{10}$/) && !(mobileNo.match(/0{5,}/))) {
 this.setState({
 mobileNoMsg: '',
 validMobileNo: false
 });
 } else {
 this.setState({
 mobileNoMsg: 'Please enter a vaild mobile number.',
 validMobileNo: true
 });
 }
 if (city !== '') {
 this.setState({
 cityMsg: '',
 validCity: false
 });
 } else {
 this.setState({
 cityMsg: 'Please enter a vaild city.',
 validCity: true
 });
 }
 if (empType !== 'Self-Employed') {
 this.setState({
 empTypeMsg: '',
 validEmpType: false
 });
 } else {
 this.setState({
 empTypeMsg: 'Some msg',
 validEmpType: true
 });
 }
 if (salary !== '') {
 this.setState({
 salaryMsg: '',
 validSalary: false
 });
 } else {
 this.setState({
 salaryMsg: 'Please enter a vaild salary.',
 validSalary: true
 });
 }
 }
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Feb 28, 2019 at 9:40
\$\endgroup\$
3
  • \$\begingroup\$ For completeness, can you include the code for setState() as well? \$\endgroup\$ Commented Feb 28, 2019 at 15:02
  • \$\begingroup\$ @200_success setState() is native to react \$\endgroup\$ Commented Feb 28, 2019 at 23:18
  • \$\begingroup\$ Honestly, I would look at using a framework like Yup for doing form validation. \$\endgroup\$ Commented Nov 28, 2019 at 23:47

1 Answer 1

1
\$\begingroup\$

Validation is so common that I recommend generalizing it a little bit (not too much though, there are too many special cases).

One way is to create validations, schema, and data separate from each other. For example:

const validators = {
 required: (config, value) => value !== '',
 mobileNo: (config, value) => value.match(/^(\+\d{1,3}[- ]?)?\d{10}$/) && !(value.match(/0{5,}/)),
 equal: (config, value) => value === config.value
}
const validate = (data, schema) => {
 const messages = {}
 for(let [name, rules] of Object.entries(schema)){
 for(let rule of rules){
 if(!validators[rule.type](rule, data[name])){
 if(!messages.hasOwnProperty(name)) messages[name] = []
 messages[name].push(rule.msg)
 }
 }
 }
 return messages
}
const schema = {
 firstName: [{type: 'required', msg: 'Please enter a valid first name.'}],
 lastName: [{type: 'required', msg: 'Please enter a valid last name.'}],
 mobileNo: [{type: 'required', msg: 'Please enter a mobile number'}, {type: 'mobileNo', msg: 'Please enter a valid mobile number.'}],
 city: [{type: 'required', msg: 'Please enter a vaild city.'}],
 empType: [{type: 'equal', value: 'Self-Employed', msg: 'Some msg'}],
 salary: [{type: 'required', msg: 'Please enter a vaild salary.'}],
}
// In react component
validateForm(){
 const validationMessages = validate(this.state.data, schema)
 this.setState({validationMessages})
}

You can take this much further by adding templated validation messages, and fancy rules of all sorts. But I recommend keeping it simple. You can make multiple variants of the validate function for different needs as they come.

answered Mar 3, 2019 at 12:55
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.