0% found this document useful (0 votes)
93 views

React Form Field Validation

This document discusses how to implement instant form field validation in React using controlled inputs. It explains how to: 1) Validate form fields on every change and represent errors in an object. 2) Display errors by marking invalid fields red without additional text. 3) Connect validation to the form by running validation on render, disabling submit if errors exist, and conditionally adding a class to invalid fields. 4) Refine the validation to not mark fields red immediately on focus to improve the user experience.

Uploaded by

Naser
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
93 views

React Form Field Validation

This document discusses how to implement instant form field validation in React using controlled inputs. It explains how to: 1) Validate form fields on every change and represent errors in an object. 2) Display errors by marking invalid fields red without additional text. 3) Connect validation to the form by running validation on render, disabling submit if errors exist, and conditionally adding a class to invalid fields. 4) Refine the validation to not mark fields red immediately on focus to improve the user experience.

Uploaded by

Naser
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich

Gosha Arinich

articles
available for hire
forms book

Instant form field validation with React's controlled inputs


03 Jan 2017

If you’ve followed along, you know about controlled inputs and simple things they enable, like disabling the Submit button when some fields are missing or invalid.

We’re not stopping there, of course!

While a disabled button is nice, the reason for that is not immediately apparent to the users. They have no idea what’s their mistake here. They don’t even know
which field is causing that…

And that ain’t pretty. We absolutely have to fix that!

As a little refresher from before:

Using controlled inputs implies we are storing all the input values in our state. We can then evaluate a particular condition on every value change, and do something
based on it. Previously all we did was disable the button.

https://goshakkk.name/instant-form-fields-validation-react/ 1/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich

We used a simple expression to compute whether the button should be disabled (aka when either of email or password was empty):
const { email, password } = this.state;
const isEnabled = email.length > 0 && password.length > 0;

<button disabled={!isEnabled}>Sign up</button>;

It got the job done. Now, to mark the bad inputs, we need to ask ourselves a couple of questions.

How are the errors going to be shown?


This is an important question to ask yourself, as different requirements might warrant different error representations.

There are many ways to show input errors. For example, you could:

display a ❌

mark red the inputs that contain bad data

display errors right next to the relevant inputs


display a list of errors at the top of the form

any combination of the above, or something else!

Which one should you use? Well, it’s all about the experience you want to provide. Pick what you want.

For the purpose of this post, I’m going to do with the simplest one — marking red the bad inputs, without anything else.

How to represent errors?


The way you want to display errors influences how you might represent them.

To indicate whether a particular input is valid, without any additional information as to why it is invalid, something like this will suffice:

errors: {
name: false,
email: true,
}

false means no errors aka entirely valid; true means a field is invalid.

In future, if we decide we need to store the reason something was invalid, we can replace true/false here with a string containing an error message.

But how is this error object created?


Now that we know how we want to display the errors AND know how to represent them, there’s something crucial missing.

How to actually get errors?

Or, another way to put it is, how to take existing inputs, validate then and get the error object we need?
https://goshakkk.name/instant-form-fields-validation-react/ 2/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich
We are going to need a validation function for that. It will accept the current values of the fields and returns us the errors object.

Continuing the sign up form example, recall we had this:


const { email, password } = this.state;
const isEnabled = email.length > 0 && password.length > 0;

We can, in fact, turn that piece of logic into a valudation function that will:

have email: true if email is empty; and


have password: true if password is empty.
function validate(email, password) {
// true means invalid, so our conditions got reversed
return {
email: email.length === 0,
password: password.length === 0
};
}

The remaining piece


There’s one piece of the puzzle remaining.

We have a validation function and know how we want to show errors. We also have a form.

It’s time to connect the dots now.

Run the validator in render.

It’s no use having the validate function if we never call it. We want to validate the inputs every time (yes, every time) the form is re-rendered, which can be
because of a new character in the input.
const errors = validate(this.state.email, this.state.password);

Disable the button.

This is a simple one. The button should be disabled if there are any errors, or, in other words, if any of errors values are true.

const isEnabled = !Object.keys(errors).some(x => errors[x]);

Mark the inputs as erroneous.

This can be anything. For our case, adding an error class to the bad inputs will be just enough.
<input
className={errors.email ? "error" : ""}
...
/>

And we can add a simple CSS rule:


.error {
border: 1px solid red;
}

InstantInstant
form eld
form
validation
eld validat… Open in Editor
1/2
index.js style.css package.json
Made by goshakkk Enter email
1 import React from "react";
2 import ReactDOM from "react-dom";
Files Enter password
3
4 import "./style.css";
public
5
index.html
6 function validate(email, password) { Sign up
7 // true means invalid, so our conditions got reverse
src
8 return {
9 index.js
email: email.length === 0,
10 password: password.length === 0
style.css
11 };
12 }package.json
13
Dependencies
14 class SignUpForm extends React.Component {
15 constructor() {
npm dependencies
16 super();
17
react this.state = { 16.5.2
18 email: "",
react-dompassword: "",
19 16.5.2
20
react-scripts 2.0.3
21 everFocusedEmail: false,
Console 0 Problems 0
22 everFocusedPassword: false,

One more thing


If you look at the JS Bin above, you may notice something odd. The fields are marked red by default, because empty fields are invalid but…

We never even gave a user a chance to type first! Also, the fields are still red while focused for the first time.

https://goshakkk.name/instant-form-fields-validation-react/ 3/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich
This is bad-ish for UX.

We are going to do that by adding the error class if the field was in focus at least once but has since been blurred.

This ensures that the first time a user focuses the field, the error won’t appear right away, but instead, only when the field is blurred. On subsequent focuses, though,
the error would be shown.

This is easily achievable by using the onBlur event, and state to keep track of what was blurred.
class SignUpForm extends React.Component {
constructor() {
super();
this.state = {
email: '',
password: '',
touched: {
email: false,
password: false,
},
};
}

// ...

handleBlur = (field) => (evt) => {


this.setState({
touched: { ...this.state.touched, [field]: true },
});
}

render()
const shouldMarkError = (field) => {
const hasError = errors[field];
const shouldShow = this.state.touched[field];

return hasError ? shouldShow : false;


};

// ...

<input
className={shouldMarkError('email') ? "error" : ""}
onBlur={this.handleBlur('email')}

type="text"
placeholder="Enter email"
value={this.state.email}
onChange={this.handleEmailChange}
/>
}
}

InstantInstant
form eld
form
validation
eld validation 2/2 Copy Link Open in Editor
2/2
index.html package.json style.css index.js
Made by goshakkk Enter email
1 import React from "react";
2 import ReactDOM from "react-dom";
Files Enter password
3
4 import "./style.css";
public
5
index.html
6 function validate(email, password) { Sign up
7 // true means invalid, so our conditions got reversed
src
8 return {
9 index.js
email: email.length === 0,
10 password: password.length === 0
style.css
11 };
12 }package.json
13
Dependencies
14 class SignUpForm extends React.Component {
15 constructor() {
npm dependencies
16 super();
17
react this.state = { 16.5.2
18 email: "",
react-dompassword: "",
19 16.5.2
20
react-scripts 2.0.3
21 touched: {
Console 0 Problems 0
22 email: false,

Not so hard, right?

Final touches
Note that shouldMarkError only affects field presentation. The status of the submit button still depends only on validation errors.

A nice final touch might be to force display of errors on all fields, regardless of whether they have been in focus, when the user hovers or clicks a disabled submit
button.

Implementing this is left as an exercise for you.

If you are digging this series on handling forms with React, subscribe below to get new posts straight in your inbox.

https://goshakkk.name/instant-form-fields-validation-react/ 4/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich
Think your friends would dig this article, too?

Facebook

https://goshakkk.name/instant-form-fields-validation-react/ 5/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich

Twitter

https://goshakkk.name/instant-form-fields-validation-react/ 6/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich

Google+

https://goshakkk.name/instant-form-fields-validation-react/ 7/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich

Tumblr

Know how you tear your hair out when your designer asks to make a nice form?

But what if you could implement the form experience your users deserve?

The Missing Forms Handbook of React can help you breeze through your React forms. You will learn how forms fit into React and see how to implement common
form patterns.

The excerpt contains a table of contents and two chapters: on building an intuition for forms and handling various form controls.

First name Email Get your free sample!


No spam. I will occasionally send you my posts about JavaScript and React.

https://goshakkk.name/instant-form-fields-validation-react/ 8/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich

Know how you tear your hair out when your designer asks to make a nice form?

But what if you could implement the form experience your users deserve?

The Missing Forms Handbook of React can help you breeze through your React forms. You will learn how forms fit into React and see how to implement common
form patterns.

The excerpt contains a table of contents and two chapters: on building an intuition for forms and handling various form controls.

Get your free sample! to

More about forms in React:

Guide to forms
Controlled and uncontrolled form inputs in React don't have to be complicated
Should you store your form state in Redux?
Form recipe: Conditionally disabling the Submit button
Collecting data from a wizard form
Making dynamic form inputs with React
How do you make a React form start out with some values prefilled when editing?
Why not field-level validations?
Transitioning from uncontrolled inputs to controlled
Validating a React form upon submit
How to handle validations involving several fields?
Here's what you can do to make migrating your forms to Redux easier in the future
The Missing Forms Handbook of React
My playlist on Egghead

If you need a mobile app built for your business or your idea, there's a chance I could help you with that.
Leave your email here and I will get back to you shortly.

11 Comments goshakkk 
1 Login

 Recommend 2 t Tweet f Share Sort by Best

Join the discussion…

LOG IN WITH
OR SIGN UP WITH DISQUS ?

Name

Adam Goldman • 2 years ago


better move `shouldMarkError` out of render, so it won't get recreated every time ;)
2△ ▽ • Reply • Share ›

yaniv > Adam Goldman • 2 months ago


how would you do this?
△ ▽ • Reply • Share ›

Adam Goldman > yaniv • 2 months ago


Here's the code in a gist:

https://gist.github.com/gol...
△ ▽ • Reply • Share ›

Show more replies

yaniv • 2 months ago


Hi, thanks for article.

the question, how can I mark dropdown if I have not choose any value from dropdown, but already have opened it with shouldMarkError? so I can
mark dropdown field with red border? [note: first option is empty [value = ""])

thanks for help..


△ ▽ • Reply • Share ›

Gosha Arinich Mod > yaniv • 2 months ago

You can use the `onBlur` prop to set some state about the dropdown (I'm assuming a `select` with `option`s) having been "touched", just like
ith i t
https://goshakkk.name/instant-form-fields-validation-react/ 9/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich
with inputs.
△ ▽ • Reply • Share ›

yaniv > Gosha Arinich • 2 months ago


I already have tried it, not works :(
△ ▽ • Reply • Share ›

Billy • 3 months ago


Hi, i have built custom hook for easy form validation. i think it's gonna make your life a lot easier comes to form. you can leverage your html validation
knowledge.
Github: https://github.com/bluebill...
Website: http://react-hook-form.now.sh
△ ▽ • Reply • Share ›

Tanguy Krotoff • 2 years ago • edited


I've created a small (~300 lines of code) lib for React that shared similarities with your approach (although it does not disable the submit button):
https://github.com/tkrotoff...

<input type="password" name="password" value="{this.state.password}" onchange="{this.handleChange}" pattern=".{5,}" required=""/>


<fieldfeedbacks for="password" show="all">
<fieldfeedback when="valueMissing"/>
<fieldfeedback when="patternMismatch">Should be at least 5 characters long</fieldfeedback>
<fieldfeedback when="{value" ==""> !/\d/.test(value)} warning>Should contain numbers</fieldfeedback>
<fieldfeedback when="{value" ==""> !/[a-z]/.test(value)} warning>Should contain small letters</fieldfeedback>
<fieldfeedback when="{value" ==""> !/[A-Z]/.test(value)} warning>Should contain capital letters</fieldfeedback>
<fieldfeedback when="{value" ==""> !/\W/.test(value)} warning>Should contain special characters</fieldfeedback>
</fieldfeedbacks>

Online demo: https://codepen.io/tkrotoff...


Bootstrap 4 demo: https://codepen.io/tkrotoff...
△ ▽ • Reply • Share ›

Jez > Tanguy Krotoff • a year ago


Very useful, thanks. Coming from an angular background this makes more sense than many of the solutions out there, and is nice & simple.
1△ ▽ • Reply • Share ›

Jessi Deer • 2 years ago • edited


Nice article, thank you for sharing!

const hasError = errors[field];


const shouldShow = this.state.touched[field];
return hasError ? shouldShow : false;

This can be replaced with:

return errors[field] && this.state.touched[field];

△ ▽ • Reply • Share ›

Nils Rasmusson • 2 years ago


This was a super helpful article and exactly what we needed for a project we're working on. Thanks so much for taking the time to explain it all out!

One thing we did differently, in case it helps someone else, was to handle individual field validation in the field component itself. We passed the
validity of each field down to the component, then let each field handle the display of the error. We then used a function to crawl through each of the
keys of state and look for errors. This set a 'isDisabled' variable that we used to disable (or not) the submit button.

Anyway, awesome job and thanks again!


△ ▽ • Reply • Share ›

✉ Subscribe d Add Disqus to your siteAdd DisqusAdd 🔒 Disqus' Privacy PolicyPrivacy PolicyPrivacy

Posts

on React

on Forms in React

on React Native

on Rails

Products

The Missing Forms


Handbook of React

https://goshakkk.name/instant-form-fields-validation-react/ 10/11
7/16/2019 Instant form field validation with React's controlled inputs - Gosha Arinich
Hire me

Do you need a mobile app?

Previous works

Contact

Subscribe

Twitter

GitHub

Email

Privacy

Heorhi Arynich

https://goshakkk.name/instant-form-fields-validation-react/ 11/11

You might also like