skip to Main Content

I have string "-11.5" inside React state. Sometimes when passing this string to either Number(state) or parseFloat(state) I get NaN.

This doesn’t occur when passing string literal or const variable instead of state to either of these functions.

Example:

const [state, setState] = useState("-11.5");
const c = "-11.5";

console.log(state, Number(state), parseFloat(state)); // -> -11.5 NaN NaN
console.log("-11.5", Number("-11.5"), parseFloat("-11.5")); // -> -11.5 -11.5 -11.5
console.log(c, Number(c), parseFloat(c)); // -> -11.5 -11.5 -11.5

Why does this happen?

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out, it's kinda embarassing:

    I constructed string in state using toLocaleString:

    const num = -11.5;
    const str = num.toLocaleString("sl-SI");
    

    At this point str is "−11,5". Note that (U+2212) is not - (U+002D), even though they are visually exactly the same.

    Then I converted it naively into decimal string:

    const dec = str.replaceAll(",", ".");
    
    // So we have now dec = "−11.5" where "−" is U+2212
    parseFloat(dec); // NaN
    

    So problem occurs due to toLocaleString with sl-SI locale using U+2212 instead of U+002D minus sign, which parsers don't understand. Fix is relatively simple dec.replaceAll("−", "-").


  2. Note that useState is asynchronous. If you immediately try to use that state you might not get the expected value.

    Consider using useEffect, it runs after any state changes and it will always log the correct value.

    useEffect(() => {
        console.log(state, Number(state), parseFloat(state));
    }, [state]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search