使用 parseFloat 时,React onChange 正在吞下我的小数点

React onChange is swallowing my decimal when using parseFloat

我有一个简单的 onChange,它接受用户的输入并对其进行解析并将状态设置为呈现。这是代码。

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;

我不明白我的小数点在哪里。我知道没有适当的验证来阻止用户输入字母,但这只是一个示例应用程序来测试我 运行 遇到的这个问题。当我输入小数点时,不会呈现。我哪里错了?

只要您按下一个键,onChange 事件就会发生,这会导致函数 运行 并且 parseFloat 从您的号码中删除 .,这就是为什么您最终得到 12 而不是 1.2,所以在使用 parseFloat 之前你需要检查最后一个字符是否是 . 并在之后添加回来。

问题是 React 的 onChange 的行为不像浏览器的 onChange 它的行为像 onInput 所以每次你输入一个值时它都会被调用。这导致您的 parseFloat 实际上解析 1. 而不是 1.2 并且 1. 的解析值是 1

将您的默认状态更改为 foo: 1.11 - 您将能够编辑此值(这不是解决方案,而是线索)。

这里的问题是 parseFloat,当您键入新的浮点值时,它会从字符串末尾修剪点,而 return 对于您的字符串 parseFloat('0.')0,因此你看到你的行为...

正如其他人所说,问题在于数字类型没有包含足够的输入状态信息,因此当 1. 进行往返时,它会丢失 .

换句话说,输入是一个用于编辑字符串的小部件,您的状态不包含足够的信息来正确地重新创建该字符串,而是小数点丢失。

因此,一种解决方案是将其作为字符串存储在您的状态中,也许称为 inputValue。然后,使用单向数据流,管理该字符串与非常明确地以数字方式考虑它的代码部分之间的转换。从字符串转换为数字是危险的——并非每个字符串都代表一个数字,因此这部分代码需要处理验证(而不是忘记文本输入)。正如您已经观察到的那样,从数字转换为字符串是有风险的,因此只有在有充分理由的情况下才应该这样做(例如,服务器正在推送数据在其他地方发生变化的事件,将其换出).