React:没有负值、小数或零值的数字输入

新手上路,请多包涵

考虑类型 number 的输入,我希望这个数字输入只允许用户输入一个 正数非零整数(无小数)数字。使用 minstep 的简单实现如下所示:

 class PositiveIntegerInput extends React.Component {
  render () {
  	return <input type='number' min='1' step='1'></input>
  }
}

ReactDOM.render(
  <PositiveIntegerInput />,
  document.getElementById('container')
)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<p>
  Try to input a decimal or negative number or zero:
</p>
<div id="container"></div>

如果用户坚持只单击数字输入中的向上/向下箭头,上面的代码工作正常,但是一旦用户开始使用键盘,他们输入数字就没有问题了 -42 , 3.140

好的,让我们尝试添加一些 onKeyDown 处理来禁止这个漏洞:

 class PositiveIntegerInput extends React.Component {
	constructor (props) {
    super(props)
    this.handleKeypress = this.handleKeypress.bind(this)
  }

  handleKeypress (e) {
    const characterCode = e.key
    if (characterCode === 'Backspace') return

    const characterNumber = Number(characterCode)
    if (characterNumber >= 0 && characterNumber <= 9) {
      if (e.currentTarget.value && e.currentTarget.value.length) {
        return
      } else if (characterNumber === 0) {
        e.preventDefault()
      }
    } else {
      e.preventDefault()
    }
  }

  render () {
    return (
      <input type='number' onKeyDown={this.handleKeypress} min='1' step='1'></input>
    )
  }
}

ReactDOM.render(
    <PositiveIntegerInput />,
    document.getElementById('container')
)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<p>
  Try to input a decimal or negative number or zero:
</p>
<div id="container"></div>

现在一切似乎都按预期工作了。但是,如果用户突出显示文本输入中的所有数字,然后使用 0 键入此选择,则输入将允许 0 作为值输入。

为了解决这个问题,我添加了一个 onBlur 函数来检查输入值是否为 0 如果是,则将其更改为 1 :733–

 class PositiveIntegerInput extends React.Component {
	constructor (props) {
  	super(props)
    this.handleKeypress = this.handleKeypress.bind(this)
    this.handleBlur = this.handleBlur.bind(this)
  }

  handleBlur (e) {
    if (e.currentTarget.value === '0') e.currentTarget.value = '1'
  }

	handleKeypress (e) {
    const characterCode = e.key
    if (characterCode === 'Backspace') return

    const characterNumber = Number(characterCode)
    if (characterNumber >= 0 && characterNumber <= 9) {
      if (e.currentTarget.value && e.currentTarget.value.length) {
        return
      } else if (characterNumber === 0) {
        e.preventDefault()
      }
    } else {
			e.preventDefault()
    }
  }

  render () {
  	return (
    	<input
        type='number'
        onKeyDown={this.handleKeypress}
        onBlur={this.handleBlur}
        min='1'
        step='1'
      ></input>
    )
  }
}

ReactDOM.render(
  <PositiveIntegerInput />,
  document.getElementById('container')
);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<p>
  Try to input a decimal or negative number or zero:
</p>
<div id="container"></div>

有没有更好的方法来使用这种类型的标准来实现数字输入? 为输入编写所有这些开销以仅允许非零正整数似乎很疯狂……必须有更好的方法。

原文由 Cumulo Nimbus 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 890
1 个回答

如果您将其作为具有组件状态值的受控输入来执行,则可以在不符合您的条件时阻止更新状态 onChange。例如

class PositiveInput extends React.Component {
    state = {
        value: ''
    }

    onChange = e => {
        //replace non-digits with blank
        const value = e.target.value.replace(/[^\d]/,'');

        if(parseInt(value) !== 0) {
            this.setState({ value });
        }
    }

    render() {
        return (
            <input
              type="text"
              value={this.state.value}
              onChange={this.onChange}
            />
        );
     }
}

原文由 Anthony 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题