React:数字输入,无负,十进制或零值

Cum*_*bus 6 html javascript validation input reactjs

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

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

ReactDOM.render(
  <PositiveIntegerInput />,
  document.getElementById('container')
)
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

上面的代码工作正常,如果用户枝只点击向上/向下数输入箭头,但只要使用键盘的用户开始他们将进入号码,如没有问题-423.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')
)
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

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

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')
);
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*ony 4

如果您将其作为组件状态中的值的受控输入来执行,则如果状态不符合您的条件,则可以阻止更新状态 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}
            />
        );
     }
}
Run Code Online (Sandbox Code Playgroud)