Date Validation in Forms for Beyond Beginners - React - MaterialUI - Hooks -
Tags: react, javascript, typescript, validations
Published: 2020-12-16 02:38:05

## Who This Is For 
* You want dynamic (that is, validate dates before submission) and simple date validation for a non-complex form.
* You are using React Hooks and functional components. You can reverse engineer the code if you are using classes.
* You want a codesand box with clear explanations of how & why.   
* You want to know why they are called Hooks. 

*Note 1 - I assume you understand the `useState()` hook.*

*Note 2 - I’m using moment.js. If you are using a modern/supported date/time package, your implementation might vary.*

*Note 3 - This is Typescript/React. If you are new to Typescript, know that this bit of code:  `: boolean`  or `: string` after a variable declaration indicates the data type to check for. Otherwise, the implementation is the same.*

## Sandbox 
{% codesandbox ss4sh module=/src/Form.tsx%}

## Step 1 - The Date Input Setup
The calendar is built with the MaterialUI KeyboardDatePicker; see the sandbox for the full code. The code snippet below shows the key parts for date validation in the onChange callback:

```javascript
<KeyboardDatePicker
  label="Start Date" 
  // name="date”     note: intentionally commented out
  value={dates.startDate}
  onChange={(value) => handleDateChange("startDate", value)}  // ←-important part
 />
```

For most form inputs, we set state using the `event.target.name` and `event.target.value` in the `handleChange` callback.  

However, the `event` in this case is different.  The event is a `moment.js` object{}. Use  `console.log` or `debugger` to see the `event` looks like this:  

```javascript
// from the console
> event
Moment {_isAMomentObject: true, _i: Tue Dec 15 2020 09:56:21 GMT-0800 (Pacific Standard Time), _isUTC: false, _pf: {…}, _locale: Locale, …}
``` 
Because `event` is a `moment.js` object{}, we do not have a `name={something}` property via event.target.name. 

So how do we set the value to the correct state variable?

Create a generic event handler to set `startDate` and `endDate` by passing the `handleDateChange` two arguments: a string and a value. The string is a name to use as a reference (`startDate` in this case) and the event (called `value` in this case, which is moment.js object and NOT `value={dates.startDate}`) 

*Note: you could also create a `setStartDate()` and `setEndDate()` via `useState()` instead of a generic `handleEvent`.*

## Step 2 - Validation Setup
Determine if your dates can be the same or different. This feature allows the same start and end date, requiring comparison with `<=`. 

The ternary operators change two boolean values (`dateValidity` and `formValidity`) and ternary controls the display of any error message. 

The `dateValidity` connects to the `KeyboardDatePicker` error property (`error={errors.dateValidity}`); the input changes color depending on this error state. 

Form submission is controlled via `formValidity` state. If there is an error, the form displays the error and prevents submission until the error is fixed. 

## Step 3 - useEffect() Hook To Control Timing
For a user to see the error messages and error styling, first set the `dates` state variables in `handleDateChange().`  

After `handleDateChange()` runs, where and how to do the validation?  The short answer? useEffect() hook.  

```javascript
 useEffect(() => {
    validateDates();
  }, [dates]);  // ←-this is the array argument. 
```

This useEffect hook executes the callback function (`validationDates()` in this case) only if the state in the array argument (`[dates]`) changes. 

If you attempt to call `validationDates()` inside `handleDateChange()` or as a second callback to `onChange`, you experience asynchronous update and UX issues.   
   
*Note: the array argument in `useEffects` can take multiple state items (or none). If any one of the state items changes, the callback function runs.  `useEffects` is worth understanding. Check the references below for suggested readings and videos.* 



## Why Are They Called Hooks? 

When I first heard Hooks, I visualized setting something like fishing hooks into my code. The hook name, because of my mental picture, didn’t provide a clue for use.  

The React.js explanations also didn’t help: 

>“Hooks allow you to reuse stateful logic without changing your component hierarchy.”  

Ok. Fine. 

But why the name Hook? 

In science class, we learn about classes of animals (among other categories of classes). So classes, as a term of code abstraction, makes sense, but hooks as a term? Hmm...

>“Hooks are functions that let you “hook into” React state and lifecycle features from function components”  

Ok, a better attempt to explain the name. But this definition is a tautology (fancy word meaning to define X with different but similar words). 

TL:DR - A Better Hook Definition - hooks let you **connect to or or join** your functional component to a state object; previously you could not hook your functional component to state.  

This [Intro to Hooks - Official High Level Overview of Hooks](https://reactjs.org/docs/hooks-intro.html)
is helpful in understanding the problem hooks seek to solve. 

##Feedback?
Have thoughts on date validations or the above implementation?

If so, drop a note. I'd love to hear and see your examples, explanations, and other details to clarify how/why/when.



## Resources
*[Intro to Hooks - Official High Level View of Hooks](https://reactjs.org/docs/hooks-intro.html)
*[Hooks Overview - Official](https://reactjs.org/docs/hooks-overview.html)
*[Using React Hooks - LinkedIn Learning](https://www.linkedin.com/learning-login/share?forceAccount=false&redirect=https%3A%2F%2Fwww.linkedin.com%2Flearning%2Freact-hooks%3Ftrk%3Dshare_ent_url) - The clearest explanations I’ve found for why and how to use hooks. Worth the cost of a membership.
*[3 Rules of React State Management](https://dmitripavlutin.com/react-state-management/)
*[React Form Validation Using React Hooks](https://hackernoon.com/react-form-validation-using-react-hooks-5859c32280ca) - A different implementation of validating forms with `useCallBack()` hooks and form abstraction. 
*[How to Build Custom Forms with React Hooks](https://www.telerik.com/blogs/how-to-build-custom-forms-react-hooks) - Building a whole form with hooks and abstraction.