Categories
JavaScript React

How to Add a React Input with a Required Attribute?

In a React app, if we want to add input with a required attribute, then we can’t just use the required attribute since we’re supposed to handle all the form input changes ourselves.

However, we can make this task easier by using a library to make our lives easier.

The React Hook Form package lets us add an input field with a required attribute and enforce it by providing functions that we can pass into the props of an input element to enforce an input value to be entered.

To start, we run:

npm install react-hook-form

Then we can write the following to add an input box that requires an input value before form submission.

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => console.log(data);
  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
        <input name="requiredField" ref={register({ required: true })} />
        <br />
        {errors.requiredField && <span>This field is required</span>}
        <br />
        <input type="submit" />
      </form>
    </div>
  );
}

We have an input element that has the ref prop set to the object returned by the register function that’s returned by the useForm hook.

{ required: true } is passed into the register function to make this input a required input.

We also set the name attribute with a name so that we can display form validation error messages below it, which is stored in the returned errors object.

The errors object is returned by useForm and has the form validation errors with the name attribute values of each input element as the keys and true if there are errors in the input field value and false otherwise.

handleSubmit is the form submit event handler, and it doesn’t run until all form input values in the form are valid.

We just log the entered values, which are stored in the data parameter as an object with the keys being the name attribute values of each input and the values being the corresponding input values for each input.

Form validation errors are only detected after we type in something for the first time.

With the React Hook Form package, we can add a React input that acts like it has the required attribute set to true.

We can set an input to be a required input element by passing in some props.

Categories
JavaScript React

React Hook Form – a Good React Form Validation Library

Handling form input values and form validation is a pain with React apps.

We’ve to figure it out all by ourselves. Fortunately, there’re good packages out there to help us solve this problem easy.

In this article, we’ll look at how we can use the React Hook Form library as our React app form validation library.

Getting Started

To get started, we run:

npm install react-hook-form

Then we can use it to add a form with a required field by writing:

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => console.log(data);
  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
        <input name="requiredField" ref={register({ required: true })} />
        <br />
        {errors.requiredField && <span>This field is required</span>}
        <br />
        <input type="submit" />
      </form>
    </div>
  );
}

In the code above, we used the useForm hook from the react-hook-form React form validation library to return the register function to register input as a ref. We pass in { required: true } to make the form field required.

Submission won’t be made until all form fields have valid input values.

The handleSubmit function is used as our form submit handler. We just log the values that are entered. data has the input value for each field.

errors has an object with the errors. It’s smart enough to only display when it’s touched.

Validating Input Format

We can validate input patterns by passing in various properties to the object that we pass into the register function.

To add form validation for various formats and regex patterns, we can write:

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => console.log(data);
  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
        <input
          name="firstName"
          ref={register({ required: true, maxLength: 20 })}
        />
        <br />
        {errors.firstName && <span>Invalid first name</span>}
        <br />
        <input name="lastName" ref={register({ pattern: /^[A-Za-z]+$/i })} />
        <br />
        {errors.lastName && <span>Invalid last name</span>}
        <br />
        <input name="age" type="number" ref={register({ min: 18, max: 99 })} />
        <br />
        {errors.age && <span>Age is must be between 18 and 99</span>}
        <br />
        <input type="submit" />
      </form>
    </div>
  );
}

We have maxLength validation for the firstName input field to make sure that the length of the firstName input value never exceeds 20.

lastName has the pattern property in the object that we pass into register to make sure that we only enter alphabet characters as the value of lastName.

To validate age, we have the min and max values to restrict the range of age to be between 18 and 99.

We also display an error message for each input field to display an error message when the format doesn’t match the ones specified by the properties.

React Hook Form is a great React form validation library that lets us handle input value changes and form validation less code than the alternatives.

Categories
JavaScript React

Add an Input Mask to Enforce Phone Number Format

We can use the react-input-mask library to enforce the format of an input box to be a phone number.

The react-input-mask package makes this very easy.

First, we run:

npm install react-input-mask --save

to install the package in our React project.

Then we can use it by adding it component provided by the package and specify the format of the input that we want to accept.

We can then use it as follows in a React component:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  const [phone, setPhone] = React.useState("");
  return (
    <div className="App">
      <InputMask
        value={phone}
        onChange={e => setPhone(e.target.value)}
        mask="+1\(999) 999-9999"
        maskChar=" "
      />
      <p>{phone}</p>
    </div>
  );
}

We import the InuptMask component. In it, we pass in the mask prop, which contains the phone number mask.

We want to enforce the North American phone number format, so we write +1\(999) 999-9999 as the value of the mask so that we’ve to type in a North American phone number.

The value prop is the same as the value prop of a regular input element, it takes the state with the value that’s inputted.

The onChange prop is also the same as the onChange handler for an input element.

It sets the value in the input box to a state in our example by getting e.target.value and calling setPhone in it.

maskChar has the character to display when the position doesn’t have anything entered yet.

We also have the phone value displayed below the input.

Now the input box enforces the North American phone number format.

Also, we’ll see the entered value displayed after we enter something.

With the react-input-mask package, we can add a React component to enforce a phone number mask easily.

Categories
JavaScript React

How to add an Input Mask in a React App – an Example

Introduction

An input mask is a string expression that constrains user input.

In this article, we’ll look at how to use an input mask to enforce input format in a React app.

Getting Started

We can add an input that enforces an input mask in a React app.

The react-input-mask package makes this very easy.

First, we run:

npm install react-input-mask --save

to install the package in our React project.

Then we can use it by adding it component provided by the package and specify the format of the input that we want to accept.

For instance, if we want to incorporate an input that takes a North American phone number, then we can write:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  return (
    <div className="App">
      <InputMask mask="+1\(999) 999-9999" maskChar=" " />
    </div>
  );
}

The mask prop has the input mask.

And the maskChar has the character we want to cover over the unfilled parts of a mask.

We can also use the formatChars prop to specify the format characters with the characters as keys and the corresponding regex string as a value.

alwaysShowMask is a boolean prop to specify whether we want to show the mask when input is empty and has no focys.

inputRef prop lets us specify the input ref of the input element so that we can manage focus, selection, etc.

We can use the formatChars prop as follows:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  return (
    <div className="App">
      <InputMask
        formatChars={{
          "9": "[0-9]",
          a: "[A-Za-z]",
          "*": "[A-Za-z0-9]"
        }}
        mask="+1\(999) 999-9999"
        maskChar=" "
      />
    </div>
  );
}

Setting State

We can set the input value to a state by using a change handler and the useState hook as usual with the InputMask component.

For instance, we can write:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  const [phone, setPhone] = React.useState("");
  return (
    <div className="App">
      <InputMask
        value={phone}
        onChange={e => setPhone(e.target.value)}
        mask="+1\(999) 999-9999"
        maskChar=" "
      />
      <p>{phone}</p>
    </div>
  );
}

We added onChange={e => setPhone(e.target.value)} to call setPhone when the input value changes.

It also takes a value prop so that we can set the input value to the phone number that we can change.

Now when we type something into the input, we’ll see the inputted value displayed below it.

Conclusion

We can add input with format being enforced by an input mask by using the react-input-mask package.

Using the component in the package, we can set the mask to enforce the format and handle input value changes like a regular input element.

The mask format can also be adjusted to our liking.

Categories
JavaScript React

Creating 404 and Recursive Paths with React Router

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

To build single-page apps, we have to have some way to map URLs to the React component to display.

In this article, we’ll look at how to create 404 routes and recursive paths with React Router.

404 Routes

We can create 404 routes to show something when none of the routes we added are matched.

To do this, we can use the asterisk as a wildcard character.

For example, we can write the following code;

import React from "react";  
import ReactDOM from "react-dom";  
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";

function Foo() {  
  return <h3>Foo</h3>;  
}

function Bar() {  
  return <h3>Bar</h3>;  
}

function NotFound() {  
  return <h3>Not Found</h3>;  
}

function App() {  
  return (  
    <Router>  
      <div>  
        <ul>  
          <li>  
            <Link to="/">Foo</Link>  
          </li>  
          <li>  
            <Link to="/bar">Bar</Link>  
          </li>  
          <li>  
            <Link to="/doesnt-exist">Doesn't Exist</Link>  
          </li>  
        </ul> <Switch>  
          <Route exact path="/">  
            <Foo />  
          </Route>  
          <Route path="/bar">  
            <Bar />  
          </Route>  
          <Route path="*">  
            <NotFound />  
          </Route>  
        </Switch>  
      </div>  
    </Router>  
  );  
}

const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

In the code above, we have the Switch component that has the following Route:

<Route path="\*">  
    <NotFound />  
</Route>

It’ll match any URL that doesn’t match the other routes.

Therefore, when we click the Doesn’t Exist link, we’ll see Not Found.

This also applies when we type in anything other / or /bar as the relative path.

The * is the wildcard character for matching anything.

Recursive Routes

Just like any other routes, we can define routes recursively. The only difference is that we reference the component within the Route with itself.

For example, if we have an array of NEIGHBORS as follows:

const NEIGHBORS = [  
  { id: 0, name: "Jane", neighbors: [1, 2, 3] },  
  { id: 1, name: "Joe", neighbors: [0, 3] },  
  { id: 2, name: "Mary", neighbors: [0, 1, 3] },  
  { id: 3, name: "David", neighbors: [1, 2] }  
];

where the neighbors array references the id of the other entries.

Then we can define a Neighbor component and use it as follows:

import React from "react";  
import ReactDOM from "react-dom";  
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";  
import { useParams, useRouteMatch, Redirect } from "react-router";

const NEIGHBORS = [  
  { id: 0, name: "Jane", neighbors: [1, 2, 3] },  
  { id: 1, name: "Joe", neighbors: [0, 3] },  
  { id: 2, name: "Mary", neighbors: [0, 1, 3] },  
  { id: 3, name: "David", neighbors: [1, 2] }  
];

const find = id => {  
  return NEIGHBORS.find(p => p.id === id);  
};

function Neighbor() {  
  const { url } = useRouteMatch();  
  const { id } = useParams();  
  const neighbor = find(+id); return (  
    <div>  
      <h3>{neighbor.name}’s neighbors</h3> <ul>  
        {neighbor.neighbors.map(id => (  
          <li key={id}>  
            <Link to={`${url}/${id}`}>{find(id).name}</Link>  
          </li>  
        ))}  
      </ul> 
      <Switch>  
        <Route path={`${url}/:id`}>  
          <Neighbor />  
        </Route>  
      </Switch>  
    </div>  
  );  
}

function App() {  
  return (  
    <Router>  
      <Switch>  
        <Route path="/:id">  
          <Neighbor />  
        </Route>  
        <Route path="/">  
          <Redirect to="/0" />  
        </Route>  
      </Switch>  
    </Router>  
  );  
}

const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

In the code above, we have the find function to make find neighbors easy.

Then in the Neighbor component, we have:

const { id } = useParams();  
const neighbor = find(+id);

to get the id from the URL, and then find the neighbor with it using the find function.

Then we display the neighbors of the neighbor by writing:

<ul>  
    {neighbor.neighbors.map(id => (  
    <li key={id}>  
        <Link to={`${url}/${id}`}>{find(id).name}</Link>  
    </li>  
    ))}  
</ul>

Then we have a Switch component that has Neighbor again in the Route :

<Switch>  
    <Route path={`${url}/:id`}>  
        <Neighbor />  
    </Route>  
</Switch>

This is the part that’s recursive, since Neighbor references itself here. We set the path to `${url}/:id` so that when the Link s above is clicked, we’ll see the new neighbors.

Then in App , we just have the usual routes. Once again, we have path=”/:id” to find a neighbor by id .

Conclusion

We can define 404 routes easily by setting the path ‘ value of the Route to an asterisk.

To define recursive routes, we can reference routes within itself. It’s treated no differently than any other kind of route.