在onKeyDown之前反应输入onChange

时间:2020-05-11 08:03:17

标签: reactjs react-hooks

const {useMemo, useState, createRef} = React;
const InputPIN = (props) => {
  const inputRefs = useMemo(() => Array(4).fill(0).map(i=> createRef()), []);
  const [values, setValues] = useState(Array(4).fill(''));
  function handleChange(e, index){
    const typed = e.target.value.toString();
    setValues((prev)=>
      prev.map((i,jndex) => {
        if(index === jndex) return typed[typed.length-1];
        else return i;
      })
    );
    if (typed !=='' &&  inputRefs[index + 1]) inputRefs[index + 1].current.focus();
  }
  function handleBackspace(e, index) {
    if(e.keyCode === 8){
      if(inputRefs[index-1]){
        inputRefs[index - 1].current.focus();
      }
    }
  }
  return (
    <label className="InputPIN">
      {
        new Array(4).fill(0).map((i,index)=>(
        <input style={{width:50}} key={index} value={values[index]} onKeyDown={(e)=>handleBackspace(e,index)} type="text" ref={inputRefs[index]} onChange={(e)=>handleChange(e,index)} /> ) )
      }
    </label>
  )
}

const App = () => {
  return (
    <InputPIN />
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />

我正在制作一个InputPIN组件。

输入文字时,输入焦点将移至下一个输入。

,当我键入退格时,在删除当前文本后,输入焦点将移至上一个输入。但这不起作用。

在我的代码上,我正在使用onKeyDown()onChange()。 而且我猜onKeyDown()的优先级比onChange()高。

因此,我尝试将onKeyDown()更改为onKeyUp()。 但是它有我不想要的副作用。

1 个答案:

答案 0 :(得分:1)

编辑:在讨论讨论后,整个答案已更新。

我认为您可以只使用一个自定义处理程序函数,并稍微重写两个处理程序方法:

const manualUpdateInputs = (index) => {    
    const newValues = [...values];

    newValues[index] = '';
    inputRefs[index].current.focus();    
}

const handleChange = (e, index) => {
    const newValues = [...values];
    const typed = e.target.value.toString();

    newValues[index] = typed;

    if (typed !=='' &&  inputRefs[index + 1]) {
       inputRefs[index + 1].current.focus();
    }

    setValues(newValues);
}

const handleBackspace = (e, index) => {
    if(e.keyCode === 8){
        if(inputRefs[index-1] && e.target.value === '') {
            manualUpdateInputs(index - 1);
        }
    }
}

我已经更改了更新values的方式,但是您可以按照自己的方式行事,它不会改变。重要的是使用manualUpdateInputs

“窍门”是,只要您单击键盘上的某个键,就会触发handleBackspace,但是如果单击带有空白handleChange的退格键,则不会触发<input>

告诉我此实现所获得的行为是否正是您想要的(对我来说很有意义,但也许不是您想要的)。