admin管理员组

文章数量:1221402

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?

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?

Share Improve this question asked Mar 2, 2017 at 15:05 Chaim FriedmanChaim Friedman 6,2534 gold badges34 silver badges65 bronze badges 4
  • 2 What does e.target.value show in the console? – StudioTime Commented Mar 2, 2017 at 15:13
  • before parsing or after? – Chaim Friedman Commented Mar 2, 2017 at 15:16
  • ok just tried and got this. When I had just 1. I saw 1. in the console but not on the screen. When I wrote 1.2 I saw 12 in the console and the screen. – Chaim Friedman Commented Mar 2, 2017 at 15:17
  • Possible duplicate of translating between cents and dollars in html input in React – cn0047 Commented Mar 2, 2017 at 15:40
Add a comment  | 

4 Answers 4

Reset to default 9

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

The onChange event happens anytime you hit a key, which causes the function to run and parseFloat takes away . from your number, and that's why you end up having 12 instead of 1.2, so before using parseFloat you need to check whether the last character is . and add it back afterwards.

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).

Change your default state to foo: 1.11 - you will be able to edit this value (It isn't solution it is clue).

The problem here is parseFloat which is trims dot from end of string when you typing new float value, and return for your string parseFloat('0.') value 0, hence you see your behavior...

本文标签: javascriptReact onChange is swallowing my decimal when using parseFloatStack Overflow