Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React onChange is swallowing my decimal when using parseFloat

I have a simple onChange which takes the user's input pareses it and sets the state to render. Here is the code.

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      random: {
        foo: 0
      }
    }
  }

  onChange(e) {
    let random = this.state.random;
    random[e.target.name] = parseFloat(e.target.value);
    this.setState({random});
  }

  render() {
    return (
      <div className="App">
        <input onChange={this.onChange.bind(this)} type="text" name="foo" value={this.state.random.foo} />
      </div>
    );
  }
}

export default App;

What I don't understand is where my decimal is going. I know there is no validation in place to stop the user from entering letters, but this is just a sample app to test this issue I ran into. When I enter a decimal point in does not get rendered. Where am I going wrong?

like image 674
Chaim Friedman Avatar asked Mar 02 '17 15:03

Chaim Friedman


2 Answers

The problem is that React's onChange doesn't behave like the browser's onChange It behaves like onInput So it is getting called every time you type a value. This results in your parseFloat actually parsing 1. instead of 1.2 and the parsed value of 1. is 1

like image 89
Blake Plumb Avatar answered Nov 02 '22 13:11

Blake Plumb


As other have said, the problem is that the number type doesn't hold enough information about the state of the input, so when 1. makes a round trip it loses the ..

In other words, an input is a widget for editing a string, and your state doesn't contain enough information to recreate that string correctly, and instead the decimal point gets lost.

Thus, one solution is to store it as a string in your state, perhaps called inputValue. Then, using unidirectional data flow, manage the translation between that string and the parts of code that think of it numerically very explicitly. Converting from a string to a number is dangerous -- not every string represents a number, so that part of the code needs to deal with validation (and not lose track of the text input). And converting from a number to a string is risky, as you've already observed, so it should only be done when there is a good reason (for instance, the server is pushing an event that the data changed somewhere else, swap it out).

like image 22
nafg Avatar answered Nov 02 '22 14:11

nafg