Skip to content

Latest commit

 

History

History
70 lines (52 loc) · 3.55 KB

README.md

File metadata and controls

70 lines (52 loc) · 3.55 KB

Next.js with react-bootstrap and form validation

Starting from this example, this project was my experiment to see how form validation could be done easily and effectively with React Bootstrap as the UI framework.

I tried two scenarios where my goal was to minimize complexity, tediousness, and stay as true to React/HTML5 as possible.

React Hook Form is minimally intrusive, easy to use, and is fairly flexible. With React Bootstrap it only worked with the "ref" approach using register. The Controller approach didn't work for me. The downside to the "ref" approach is that I'm guessing it is using an uncontrolled strategy, which is not recommended by React.

The other approach, which I ended up preferring, was to use React Bootstrap's support for native HTML5 validation. It was easy to activate and not surprisingly integrates more easily with Bootstrap's Form.Control.Feedback component. What really sold me on this approach is that HTML5 already provides a validationMessage, described here, that conveys a helpful description of why the field is invalid.

Here is the view of the required field after the initial form submission:

As typing characters, but still below the minLength={3} declaration:

Finally, when typing at least another character the rendering flips to a positive indication and feedback removal:

With that knowledge I wrapped up the potential repetition in a little helper component that paired a Form.Control with a Form.Control.Feedback. That helper component made use of the validationMessage, the name on the input, and the invalid event fired by inputs during validation.

Using that helper component each input is about 10 lines, which is quite acceptable, for example:

<ValidatedFormControl onChange={handleChange}
                    value={values.yourName}
                    name="yourName"
                    type="text" placeholder="Enter your name"
                    required
                    minLength={3}
/>

That ValidatedFormControl doesn't require much code itself:

function ValidatedFormControl({
  value,
  onChange,
  ...props
}) {
  const [message, setMessage] = useState();
  const { controlId } = useContext(FormContext);

  return (
      <>
        <Form.Control {...props}
                      value={value}
                      onChange={event => {
                        onChange(event.target.value, event.target.name || controlId);
                        event.target.checkValidity();
                      }}
                      onInvalid={event => setMessage(
                          event.target.validationMessage)}
        />
        <Form.Control.Feedback type="invalid">
          {message}
        </Form.Control.Feedback>
      </>
  )
}

Deploy your own

Deploy this project using Vercel:

Deploy with Vercel