title: In a controlled React number input, how can you trim leading zeros?
body: <p>In the <a href="https://reactjs.org/docs/forms.html#controlled-components" rel="nofollow noreferrer">React docs</a> it says that in a controlled component, &quot;the React state be the “single source of truth”&quot;. This seems to be true except in cases with leading zeros. In the below example, you can see that the input is controlled, but in a case with leading zeros, the input value doesn't always match the state value.</p>
  <hr />
  <p><strong>The Test</strong></p>
  <p>Type leading zeros, so the value is something like <code>0010</code>.</p>
  <p>You can see that the value in <code>state</code> is an integer <code>10</code>, but the input shows <code>0010</code>.</p>
  <p>My first thought was this was because the component doesn't actually re-render, which is true. There's no state change between <code>10</code> and <code>10</code>, so no new render. This is confirmed since we don't see the 'render' console.log firing.</p>
  <p>So let's make sure we change the value. Add a <code>2</code> to change <code>0010</code> to <code>00102</code>. The value in state is now <code>102</code>, we confirm the component re-renders...but still the leading zeros persist in the input.</p>
  <hr />
  <p>This seems inconsistent as I would expect the value in the input to always match the value in state exactly. Why is this and what is a reliable way to trim leading zeros from a number input?</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="true">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>// LEADING ZEROS INPUT TEST
  // Step 1: type 0s into the input followed by any other digits
  // Step 2: see that console log and val in `p` do not have leading 0's and input val does
  
  const {useState} = React;
  
  const App = () =&gt; {
    const [val, setVal] = useState(10);
    
    const handleChange = (evt) =&gt; {
      const strVal = evt.currentTarget.value;
      console.log('string', strVal, typeof strVal);
      const intVal = parseInt(strVal, 10) || 0; // || 0 bc '' returns NaN
      console.log('int', intVal, typeof intVal);
      setVal(intVal);
    }
    
    console.log('render', val);
    
    return (
      &lt;div&gt;
        &lt;p&gt;{val}&lt;/p&gt;
        &lt;input 
          type="number"
          value={val}
          onChange={handleChange}
        /&gt;
      &lt;/div&gt;
    )
  }
  
  ReactDOM.render(
    &lt;App /&gt;,
    document.getElementById('root')
  );</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="root"&gt;&lt;/div&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"&gt;&lt;/script&gt;
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"&gt;&lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>