Have you ever used number input and added special logic on onChange event to prevent +, – and e charterers saving to state. In this article we will gonna learn how to write a util function to block these +, – and e in your number input.
Problem
Let’s see below example.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [value, setValue] = useState("");
return (
<div className="App">
<input
type="Number"
value={value}
onChange={({ target: { value } }) => {
setValue(value);
}}
/>
</div>
);
}
If you notice we are using a number input and it’s also working fine but we don’t want user to enter +, – and e while typing.
Solution
The solution is very straight forward. We will gonna write a reusable util function which basically gonna block invalid characters.
export const blockInvalidChar = e => ['e', 'E', '+', '-'].includes(e.key) && e.preventDefault();
We can simply import this function and use it on onKeyPress event.
import React, { useState } from "react";
import { blockInvalidChar } from "./blockInvalidChar";
import "./styles.css";
export default function App() {
const [value, setValue] = useState("");
return (
<div className="App">
<input
type="Number"
value={value}
onKeyDown={blockInvalidChar}
onChange={({ target: { value } }) => {
setValue(value);
}}
/>
</div>
);
}
Top comments (8)
I'm not sure if this is a problem in React, but in my experience with vanilla js and the onkeydown event it sometimes misses the last typed character (In some browsers). If you see this poblem just use the onkeyup event instead! :)
I used to cast value to number explicitly using
Number(e.target.value)
.When using onKeyDown user cannot use many keys like:
You should rather check value onChange.
This is simple and useful!
I used this, and it worked perfectly.
Could you try this on mobile please? On mobile it keeps accepting plus, minus and dot characters.
Thanks.
This works fine when user is entering the value using keyboard.
But when the user scrolls the mouse on input this doesn't work. Is there a way to block that as well?
Add this -- >
const numberInputOnWheelPreventChange = (e: any) =>
{
// Prevent the input value change
e.target.blur();
// Prevent the page/container scrolling
e.stopPropagation();
// Refocus immediately, on the next tick (after the current
// function is done)
setTimeout(() => {
e.target.focus();
}, 0);
};