React Native self-validating input

Sooner or later, you get sick of validating stuff manually.

Prototyp
Prototyped
6 min readJul 16, 2018

--

In order to be more efficient and avoid repetitive work, but still stay flexible we asked ourselves how do we structure a self-validating and reusable input component that returns both the input value and validation result to its parent?

There are a couple of marks to check:

  • component must be reusable
  • It should handle validation, label, error messages and everything else related to a single input element
  • easily extendable (to handle new requirements)
  • for now, it should handle only simple text input component
  • support for email, password, and other simpler types (name, address, notices, etc.)

While not exhaustive, this component should address validation and handling of basic data input for 90% of forms. For that special cases of weird phone numbers or special formatted discount code you can always write a custom component.

TL;DR we managed to replace more than 90% of our input fields with this component throughout the project.

Example

Say you have a screen where you have to enter an email address and name and validate both.

Something like this:

As said above, we wanted to avoid writing handlers for each specific input type. After all, you do only need two handlers — to set the value and validation state and one for submitting everything.

These two methods, together with invoking the actual component and passing neccessary props (shown below) are everything that’s required in the parent component.

Now, the input component. You will have to replace styles with your own in the code.

As you can see, the component props interface extends the default TextInput props, which means you can pass any default TextInput prop through the component and it will be applied internally.

The value change is triggered in the onEndEditing input event → every time the user submits / ends editing the value in the current input field. This will validate and update the input as soon as the user is done entering the content. This way the validation doesn’t trigger prematurely and doesn’t give validation errors while the user isn’t finished with editing the input value.

Using the changeCallback function, the value of the input and it’s validity are propagated back to the parent component.

Now, about the custom props:

  • propName = the parent component prop name you update with the input.
  • validationType = what kind of validation type is necessary
  • changeCallback = the handler the component passes it’s internal value to
  • optional = if this is set to true, input validation is disabled. Default value = false
  • editable = “false” disables editing the value if an action is performed such as submitting data to an API
  • exists = for passing let’s say, a userExists property in case you’re checking if an e-mail is already in use. Use with e-mail validationType only.
  • minLength = minimum character length
  • compareValue = used exclusively when validationType is set to ValidationMethod.Comparable. Use to pass value to compare the input value against.
  • value = the input value passed from the parent component.
  • label = display a custom label above the input. Leaving this empty hides the label.
  • emptyErrorText = custom error text when the value is empty
  • invalidErrorText = custom error text when the value is invalid

And there you have it. You can include the ValidatedInput component anywhere and it’ll self validate every time based on the passed properties. Of course, there is room for improvement, but it’s extendable and simple to use.

Best of all, at ~250 LOC for a whole ValidatedInput component, it is a whole lot less than libraries such as informed (which can handle a lot more than this though). Still, we consider this a win.

Interested in working with us? Drop us a line at hello@prototyp.digital. We are always interested in new projects and people.

Post authors: Sebastijan Dumančić and Luka Buljan

--

--

Prototyp
Prototyped

Interface company that designs, builds, and ships market-fit products for startups and enterprises.