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';
Now, we can created the component, in this case, the name is InputMask
const InputMask = () => {
}
export default InputMask;
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;
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;
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;
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;
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;
This code works on phone inputs! in that case we must use (xxx)
in the beginning of the input.
Hope you like this post!
Top comments (7)
Your demo is not opening.
Thanks for the artcile it's very useful , can you explain more about phone inputs ? where to add (XXX) ?
change the regex as per your need and it should work..
🤯 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.
its code not valide, because useEffect(()=> { setState() },[ state ]). Your useEffect will work infinity
right. we don't need that useEffect. you can print the value of
card
and verifyThanks bro! (y)