DEV Community

Cover image for Input Mask in React without libraries
Juan Manuel Crego Risso
Juan Manuel Crego Risso

Posted on

25 2

Input Mask in React without libraries

How to create a simple input mask only with React:

There are many libraries to do this, but it is always good to know how to do things that work in any type of web development. In this case we will create an entry for credit cards.

Step 1:

In a functional component we import

import React, { useState, useEffect, useRef } from 'react';
Enter fullscreen mode Exit fullscreen mode

Now, we can created the component, in this case, the name is InputMask

const InputMask = () => {

}

export default InputMask;

Enter fullscreen mode Exit fullscreen mode

Step 2:

We create first a new state, called card, and setCard is the function to modify that state, later we create a const called inputCard for the useRef hook.

import React, { useState, useEffect, useRef } from "react";

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef()
}

export default InputMask;
Enter fullscreen mode Exit fullscreen mode

Now, we return an input with a ref property binding the InputCard const

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  return (
    <>
      <input type="text" ref={inputCard} />
    </>
  );
};

export default InputMask;
Enter fullscreen mode Exit fullscreen mode

If you do not know the hook useRef I share the official React documentation for useRef in this link

Step 3:

Now, we can target the events of the input, useRef works like a eventListener in JavaScript! For that, we create a function called handleChange and pass this function to the input in a onChange event

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  const handleChange = () => {

  };

  return (
    <>
      <input type="text" ref={inputCard} onChange={handleChange} />
    </>
  );
};

export default InputMask;
Enter fullscreen mode Exit fullscreen mode

Step 4:

In handleChange we use regex (Regular expressions) in a first step we use replace to replace all the expressions that not numbers with a blank space, later we use match for grouping the digits of the credit card in four groups of four digits each one

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  const handleChange = () => {
    const cardValue = inputCard.current.value
      .replace(/\D/g, '')
      .match(/(\d{1,4})(\d{0,4})(\d{0,4})(\d{0,4})/);
    inputCard.current.value = !cardValue[2]
      ? cardValue[1]
      : `${cardValue[1]}-${cardValue[2]}
      ${(`${cardValue[3] ? `-${cardValue[3]}` : ''}`)}
      ${(`${cardValue[4] ? `-${cardValue[4]}` : ''}`)}`;
  };

  return (
    <>
      <input type="text" ref={inputCard} onChange={handleChange} />
    </>
  );
};

export default InputMask;
Enter fullscreen mode Exit fullscreen mode

Look at this, after match, we use aternary operator to set the value forinputCard in a first step, we set the condition of the second group to false, because group one will always exist, in a second step , we write many conditions, at the beginning group one, then the second group will continue, then if group three exists it will be after a -, the same is for group four...

Step 5:

Finally, we use the useEffect hook to manage the component lifecycle, inside useEffect, we set the callback for handleChange, and we specify the render when the card state changes, for this, we use setCard to save the input value on card state

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  const handleChange = () => {
    const cardValue = inputCard.current.value
      .replace(/\D/g, '')
      .match(/(\d{0,4})(\d{0,4})(\d{0,4})(\d{0,4})/);
    inputCard.current.value = !cardValue[2]
      ? cardValue[1]
      : `${cardValue[1]}-${cardValue[2]}${`${
          cardValue[3] ? `-${cardValue[3]}` : ''
        }`}${`${cardValue[4] ? `-${cardValue[4]}` : ''}`}`;
    const numbers = inputCard.current.value.replace(/(\D)/g, '');
    setCard(numbers);
  };

  useEffect(() => {
    handleChange();
  }, [card]);

  return (
    <>
      <input type="text" ref={inputCard} onChange={handleChange} />
    </>
  );
};

export default InputMask;
Enter fullscreen mode Exit fullscreen mode

This code works on phone inputs! in that case we must use (xxx) in the beginning of the input.

Demo

Hope you like this post!

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (7)

Collapse
 
jaisaravanan_dev profile image
Jai Saravanan β€’

Your demo is not opening.

Collapse
 
anisamirouche profile image
Anis Amirouche β€’

Thanks for the artcile it's very useful , can you explain more about phone inputs ? where to add (XXX) ?

Collapse
 
kiranmantha profile image
Kiran Mantha β€’

change the regex as per your need and it should work..

Collapse
 
iqrivas profile image
Denisse Rivas β€’

🀯 Thanks for sharing! I like to always first try to look for how to do it without libraries. I like how you built the structure step by step, it was easy to understand.

Collapse
 
aman009006 profile image
Aman Mamashov β€’

its code not valide, because useEffect(()=> { setState() },[ state ]). Your useEffect will work infinity

Collapse
 
kiranmantha profile image
Kiran Mantha β€’

right. we don't need that useEffect. you can print the value of card and verify

Collapse
 
jonathanafranio profile image
Jonathan Afranio β€’

Thanks bro! (y)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

πŸ‘‹ Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay