simple-react-validator: Validation not working in functional component with hooks

I am trying to use is in the functional component using React Hooks but its now showing up the validation message on UI

My React version is below “react”: “^16.8.6”, “react-dom”: “^16.8.6”,

Below is my code, Please check if I am missing anything.

import React from "react";
import SimpleReactValidator from "simple-react-validator";

export default function ExampleForm (){
  const [values, setValues] = React.useState({
    title: 'There was a server error the prevented the form from submitting.',
    email:'',
    review:''
  });

  const  handleChange = name => event => {
    setValues({ ...values, [name]: event.target.value });
  };

  const validator = new SimpleReactValidator({
    className: 'text-danger',
    messages: {
      email: 'That is not an email.',
    },
    validators: {
      ip: {
        message: 'The :attribute must be a valid IP address.',
        rule: function(val, params, validator) { 
          return validator.helpers.testRegex(val,/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/i) && params.indexOf(val) === -1
        }
      }
    }
  });

  const submitForm= ()=> {
    if (validator.allValid()) {
      alert('You submitted the form and stuff!');
    } else {
      validator.showMessages();
    }
  }

  return (
    <div className="container">
      <div className="form-group">
        <label>Title</label>
        <input className="form-control" value={values.title}  onChange={handleChange("title")} />
 
        {/**********   This is where the magic happens     ***********/}
        {validator.message('title', values.title, 'required|alpha')}
 
      </div>
      <div className="form-group">
        <label>Email</label>
        <input className="form-control" value={values.email} onChange={handleChange("email")} />
 
        {/**********   This is where the magic happens     ***********/}
        {validator.message('email', values.email, 'required|email')}
 
      </div>
      <div className="form-group">
        <label>Review</label>
        <textarea className="form-control" value={values.review} onChange={handleChange("review")} />
 
        {/**********   This is where the magic happens     ***********/}
        {validator.message('review', values.review, 'required|min:20|max:120')}
 
      </div>
      <button className="btn btn-primary" onClick={submitForm.bind(this)}>Save Review</button>
    </div>
  );
}

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 1
  • Comments: 26 (3 by maintainers)

Most upvoted comments

You can also use force update after a form submit to show all the messages at once:

const simpleValidator = useRef(new SimpleReactValidator())
const [, forceUpdate] = useState();

submitForm() => {
  const formValid = simpleValidator.current.allValid()
  if (!formValid) {
    simpleValidator.current.showMessages()
    forceUpdate(1)
  }
}

If you can use forceUpdate with hooks like that then you can initialize the SRV with forceUpdate so it will do it automatically. something like this:

const [, forceUpdate] = useState()
const simpleValidator = useRef(new SimpleReactValidator({autoForceUpdate: {forceUpdate: forceUpdate}))

submitForm() => {
  const formValid = simpleValidator.current.allValid()
  if (!formValid) {
    simpleValidator.current.showMessages()
  }
}

Here is a more advance custom hook to force rerender the component. This hook will not recreate a SimpleReactValidator instance in each rerender, tiny performance boost~

//useSimpleReactValidator.js
export default function useSimpleReactValidator(passInOptions = {}) {
    const [{ options }, forceUpdate] = React.useReducer(({ options }) => ({ options }), {
        options: passInOptions,
    });
    const simpleValidator = React.useMemo(
        () =>
            new SimpleReactValidator(
                options.autoForceUpdate
                    ? {
                          ...options,
                          autoForceUpdate: {
                              forceUpdate,
                          },
                      }
                    : options
            ),
        [options]
    );
    return [simpleValidator, forceUpdate];
}

//example
const [validator, forceUpdate] = useSimpleReactValidator({...anyOtherOptions, autoForceUpdate: true});

I have created one small hooks to solve this problem. It worked for me. Here is the repository: https://github.com/chaudharykiran/SimpleReactValidatorWithHooks

@sachin8094 Did you try to validate your input in the onBlur event? It works for me.

  const [address, setAddress] = useState()
  const simpleValidator = useRef(new SimpleReactValidator())

  <Input
    name="name"
    value={companyInformation.name}
    onChange={handleInputChange}
    onBlur={simpleValidator.current.showMessageFor('name')} />
  {simpleValidator.current.message('name', companyInformation.name, 'required')}

@sachin8094 Did you try to validate your input in the onBlur event? It works for me.

const [address, setAddress] = useState()

const simpleValidator = useRef(new SimpleReactValidator())

<Input

name="name"
value={companyInformation.name}
onChange={handleInputChange}
onBlur={simpleValidator.current.showMessageFor('name')} />

{simpleValidator.current.message(‘name’, companyInformation.name, ‘required’)}

I try this but it’s showing errors on page load not on onblur

you need to wrap onBlur={simpleValidator.current.showMessageFor(‘name’)} /> with a function.

onBlur={()=>simpleValidator.current.showMessageFor(‘name’)} />

please how do I use showMessage on this?

You have to pass true when you want to show error message.

if (notValid) {
   showMessage(true)
}

cc. @dinorhythms

I have created one small hooks to solve this problem. It worked for me. Here is the repository: https://github.com/chaudharykiran/SimpleReactValidatorWithHooks

@chaudharykiran please how do I use showMessageFor on this?

This works!

const [, forceUpdate] = useReducer((x) => x + 1, 0); const validator = useRef( new SimpleReactValidator({ autoForceUpdate: { forceUpdate: forceUpdate }}) );

Usage: onBlur={validator.current.showMessageFor(‘name’)} />

I have created one small hooks to solve this problem. It worked for me. Here is the repository: https://github.com/chaudharykiran/SimpleReactValidatorWithHooks

Awesome! This works for me. 🚀

I have created one small hooks to solve this problem. It worked for me. Here is the repository: https://github.com/chaudharykiran/SimpleReactValidatorWithHooks

This is perfect! Worked like a charm. Appreciate you for adding this.

1

save my day!

Awesome good job @h4r3en

In my case a hook’s solution is working nice. Thanks @chaudharykiran