【问题标题】:React controlled number input jumps when deleting decimal point删除小数点时反应控制的数字输入跳转
【发布时间】:2017-02-08 18:28:04
【问题描述】:

我在 React 应用程序中输入了一个受控数字,当我删除小数点右侧的所有数字时,小数点本身也会被删除。所以当我有1.1,并删除最右边的1,它应该留下1.;但该点也被自动移除,留下1,光标移到最前面。

有关最小示例,请参阅此小提琴:https://jsfiddle.net/sashee/e00s7h9d/。只需在输入上按退格键即可观察行为。

经过一番谷歌搜索,我认为问题的根源在于1.被视为1,无法从输入中提取当前值。

因此,当我删除最右边的 1 时,会发生以下情况:

  • 调用更改处理程序
  • 值为1
  • React 将 state 中的值更新为 1
  • 输入现在的值为 1,而不是 1。

正如我所见,这不是错误,而是架构的奇怪结果。有没有使用数字输入的解决方法?还是我应该回退到常规文本输入?

更新

它在 Firefox 中运行良好,但在 Chrome 中却不行。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    原来是 React 本身的一个错误,请参阅 this PR

    从 15.5.4 开始修复,见this fiddle:

    <script src="https://unpkg.com/react@15.5.4/dist/react-with-addons.js"></script>
    <script src="https://unpkg.com/react-dom@15.5.4/dist/react-dom.js"></script>
    

    【讨论】:

      【解决方案2】:

      当您删除小数点后的数字时,您是否希望保留该小数点?这与其说是一个 React 问题,不如说是一个通用的 HTML 问题。就像您提到的,如果您希望在输入数字时显示小数点,那么您可以将type="number" 更改为type="text"

      另外,我想指出,在您的初始状态下,您将值设置为字符串,然后字符串"1.1" 被强制转换为数字1.1。为了保持一致性,如果您的输入为 type="number",则应将初始状态设置为一个数字,或者将初始状态保留为字符串并将输入更改为 type="text"

      如果您希望框中的数字在每次按下向上或向下箭头时增加或减少 0.1,请将 step 更改为 step="0.1"

      【讨论】:

      • 其实e.target.value返回的是字符串,而不是数字,所以是一致的。一个可能的用例是将 1.1 更改为 1.25 。在这种情况下,我单击末尾,删除最后一个 1,然后输入 25。但是随着我正在编辑的数字发生变化,我无法做到。跨度>
      • 哦,我现在看到了这个问题,很抱歉我误解了这个问题。我相信这个问题可以很好地了解 OP 的问题:stackoverflow.com/questions/39672804/…
      【解决方案3】:

      问题是您将input 定义为type="number",但您输入的值是一个字符串。当字符串"1." 转换为数字时,它会丢失十进制值。

      // Example of string "1." getting converted to a number
      parseInt("1.", 10) // 1
      

      如何解决:

      正如@Yo Wakita 在他的回答中所说,只需使用字符串输入即可。然而!您可以使用 RegEx 轻松禁止非数字:

      _onChange(e) {
        // This will match all signed/unsigned floats
        // Pattern credit: http://stackoverflow.com/a/16951568/2518231
        // You'll probably want to store this as a default prop so that it isn't generated on every onChange
        var regex = new RegExp(/^-?\d*\.?\d*$/);
      
        if (regex.test(e.target.value) ) {
          this.setState({val: e.target.value})
        } else {
          alert('Sorry, only numbers are allowed.');
        }
      },
      

      【讨论】:

        猜你喜欢
        • 2013-02-06
        • 2018-02-10
        • 1970-01-01
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        • 2019-08-02
        • 2014-06-11
        相关资源
        最近更新 更多