0

I have a numeric input, which I want to validate with an onChange, but when said input is cleared, react throws ReferenceError: value is not defined which is understandable - it has nothing to validate.

I'm using this approach [Answer]

I'm using functional components and here is my code snippet:

   const [formData, setFormData] = React.useState({
        userTeamChosen: "",
        eventNumber: 0,
        value: 0,
        ethValue: 0})

    function handleNumeric(event) {
        const { name, checkedValue, min, max } = event.target
        value = Math.max(Number(min), Math.min(Number(max), Number(value)));
        setFormData(prevFormData => {
            return {...prevFormData,[name]: checkedValue}})}

    <input
        type="number"
        name="value"
        value={formData.value}
        onChange={handleNumeric}
        min="5"
        max="10000000"/>

How should I change my validation, to keep in onChange, but without erroring, when the input is empty? Thanks in advance!

1
  • What is the value variable? which is getting assigned Math.max? Commented Jul 13, 2022 at 12:43

4 Answers 4

1

There is no a checkedValue property in the number input element, Use valueAsNumber or value instead.

function handleNumeric(event) {
    const { name, valueAsNumber, min, max } = event.target
    const result = Math.max(+min, Math.min(+max, !Number.isNaN(valueAsNumber) ? valueAsNumber : +min));
    setFormData(prevFormData => {
        return {...prevFormData,[name]: result}})}
Sign up to request clarification or add additional context in comments.

2 Comments

You really should not be changing the formData directly (ie: formData.value) when using React useState. You should only use the function provided by useState, in this case setFormData This solution simply writes over the formData variable directly which coerces any possible NaN cases, thus hiding errors. The error is avoided because when you try to access it in the setFormData, it was already coerced. Better to check for NaN before calling setFormData.
Yes, I know about settingstate by setState, but I missed it because I get the code by copying and pasting, Thanks for notifying me about valueAsNumber I didn't know about it producing NaN if the input with an empty value. I just update it.
0

Looks like you were very close to solving this one yourself :D

The only errors I noticed were the value variables not being declared or defined anywhere, to solve this I just added formData so that react would know that it's the formData's value being used and not some random value

function handleNumeric(event) {
    const { name, checkedValue, min, max } = event.target
    formData.value = Math.max(Number(min), Math.min(Number(max), Number(formData.value)));
    setFormData(prevFormData => {
        return {...prevFormData,[name]: checkedValue}})}

1 Comment

This solved the inital problem, but caused more errors down the line, solution below fully solved it :)
0

You should call

 function handleNumeric(event) {
        const { name, checkedValue, min, max } = event.target
        formData.value = Math.max(Number(min), Math.min(Number(max), Number(formData.value)));
        setFormData(prevFormData => {
            return {...prevFormData,[name]: checkedValue}})}

Comments

0

A number input is considered valid when empty. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number. So if you empty the input and try to check valueAsNumber it will return NaN. You can check for this case using isNaN():

    function handleNumeric(event) {
        const { name, checkedValue, min, max } = event.target
        if (isNaN(checkedValue)) checkedValue = 0;
        value = Math.max(Number(min), Math.min(Number(max), Number(checkedValue)));
        setFormData(prevFormData => {
            return {...prevFormData,[name]: checkedValue}})}

Other than that, your solution should be working fine in all other cases. Placing a required attribute on the number input may help as well since it will ask the browser to prevent users from emptying the input.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.