I have a controlled select in React with the values 0, 1, 2, 3, 4, 5, '5 ', 'unknown'
. When selecting or changing the value I'm getting a string for every value instead of a number for the values 0, 1, 2, 3, 4 and 5.
I was searching on Stackoverflow and found a solution where the value is wrapped with parseInt
but since I also have strings as possible values I'm getting 5 for the '5 ' string and NaN for 'unknown'.
Someone a working solution?
Form component
...
const { formData, handleInputChange, handleSubmit } = useForm();
const options = [
{ label: 0, value: 0 },
{ label: 1, value: 1 },
{ label: 2, value: 2 },
{ label: 3, value: 3 },
{ label: 4, value: 4 },
{ label: 5, value: 5 },
{ label: '5 ', value: '5 ' },
{ label: "I don't know", value: 'unknown' },
];
return (
<form onSubmit={handleSubmit(submit)}>
<select id="numberOfElectricityMeters" name="numberOfElectricityMeters" value={formData.numberOfElectricityMeters} onChange={handleInputChange}>
<option value=''>Choose an option</option>
{options.map((option, i) => (
<option key={i} value={option.value}>
{option.label}
</option>
))}
</select>
<select id="numberOfGasMeters" name="numberOfGasMeters" value={formData.numberOfGasMeters} onChange={handleInputChange}>
<option value=''>Choose an option</option>
{options.map((option, i) => (
<option key={i} value={option.value}>
{option.label}
</option>
))}
</select>
</form>
)
useForm
const handleChange = (e) => {
if (e.target.type === 'checkbox') {
setFormData((currentValues) => ({ ...currentValues, [e.target.name]: e.target.checked }));
} else {
setFormData((currentValues) => ({ ...currentValues, [e.target.name]: e.target.value }));
}
};
CodePudding user response:
With isNaN
you can check if the value contains string. (ex: '5 ')
if isNan is true, value not parse number.
const handleChange = (e) => {
....
....
var value = !isNaN(e.target.value) && parseInt(e.target.value) ?
parseInt(e.target.value) : e.target.value;
setFormData((currentValues) => ({ ...currentValues, [e.target.name]: value }));
...
...
};
CodePudding user response:
When you use the parseInt()
method, it parses up to the first non-digit and returns whatever it had parsed, so parsing '5 '
will return you a solid 5
, like you have experienced. To solve this, you can use Number()
function, because it tries to parse the entire string to a number, and if it is not possible, it returns a NaN
value.
So, you can implement a custom parser and use it instead of parseInt
;
const customParser = (value) => {
if(!value) return value;
const parsedVal = Number(value);
return (isNaN(parsedVal) ? value : parsedVal);
}