Reputation: 10264
const { useState } = React;
const App = () => {
const [num, setNum] = useState(0);
return (
<input type="number" value={num} onChange={(e)=>setNum(parseInt(e.target.value))} />
)
}
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />
I want to keep num
's type as Number
, not String
.
but, onChange=(e=>setNum(e.target.value))
makes num
's type String
I tried to change like this onChange={e=>setNum(parseInt(e.target.value))}
.
but, when I inputted white-space
, It occurs error.
Warning: Received NaN for the
value
attribute. If this is expected, cast the value to a string.
What is the best way to keep num
's type?
Upvotes: 2
Views: 7145
Reputation: 77
Instead of using a parseInt()
you can also use Number()
where the blank whitespace will automatically be converted to 0
.
In case you the input field to be empty you use the defaultValue
instead of value
like this
const { useState } = React;
const App = () => {
const [num, setNum] = useState(0);
//changes made below
return (
<input type="number" defaultValue={num} onChange={(e)=>setNum(Number(e.target.value))} />
)
}
ReactDOM.render(<App />, document.getElementById('root'));
However in your case the default value is 0
because that's the initial value of num
You can change it to this const [num, setNum] = useState('');
Note : It will only work for all numbers including decimals
Upvotes: 0
Reputation: 21
I resolved this issue by checking the NaN value.
<input
type="number"
onChange={e => {
Object.is(NaN, parseInt(e.target.value))
?setNum(e.target.value)
:setNum(parseInt(e.target.value))
}
}
value = {num}
/>
Upvotes: 0
Reputation: 11
I had the same issue, and I just bypassed it by having the value of the input be equal to either the state or an empty string. that way it won't affect the state of the value and it will just be an empty string.
<input
type="number"
onChange={e => setNum(parseInt(e.target.value))}
value = {num || ""}
/>
with this, I also added validation to make sure num does not stay as a NAN for long.
Upvotes: 1
Reputation: 1899
The issue stems from the fact that parseInt can break.
In case you cannot successfully parseInt your "string" input value, you will get an error. You can add a fallback to current value or reset to 0, or avoid calling setNum in case your parseInt fails.
import React, { useState } from 'react';
const App: React.FC = () => {
const [num, setNum] = useState(0);
return (
<input
type="number"
onChange={e => setNum(parseInt(e.target.value) || num)}
/>
);
};
export default App;
Upvotes: 5