在输入一个数字后在下一个输入框上传递焦点

时间:2020-04-01 16:49:23

标签: javascript reactjs

伙计们,我正在我的应用程序的OTP组件中渲染四个输入框,现在我想要的是在第一个输入框中写入一个数字后,我希望我的焦点转移到第二个输入框,因为otp的第二个数字是写在第二个输入框中。

在第三个和第四个方框中保持沉默,并在每次将数字写入输入框中时更新状态,以便我可以将4位数的选择发回服务器以进行验证 我正在使用基于类的组件。

<div className="input_boxes">
              <input type="number" className="otp_box"/>
              <input type="number" className="otp_box"/>
              <input type="number" className="otp_box"/>
              <input type="number" className="otp_box"/>
              </div>

2 个答案:

答案 0 :(得分:1)

使用 useRef 挂钩赋予焦点。

您可以使用map()重用输入字段。


有两种方法

  1. 使用 ref
  2. 数组
const inputRef = list.map(x => useRef(null));

inputRef[idx + 1].current.focus();

<input
  ref={inputRef[x]}
/>

const {useRef} = React;
const App = () => {
const list = [...Array(8).keys()];
const inputRef = list.map(x => useRef(null));
const handler = idx => () => {
  const next = inputRef[idx + 1];
  if (next) {
    next.current.focus();
  }
};
return (
  <div className="App">
    <div className="input_boxes">
      {list.map(x => (
      <div>
        <input
          key={x}
          ref={inputRef[x]}
          onChange={handler(x)}
          type="number"
          className="otp_box"
        />
      </div>
      ))}
    </div>
  </div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>

  1. 使用一个 ref 和多个 current 元素
const inputRef = useRef([]);

inputRef.current[idx + 1].focus();

<input
  ref={el => inputRef.current[x] = el}
/>

const {useRef} = React;
const App = () => {
const list = [...Array(8).keys()];
const inputRef = useRef([]);
const handler = idx => e => {
  const next = inputRef.current[idx + 1];
  if (next) {
    next.focus()
  }
};
return (
  <div className="App">
    <div className="input_boxes">
      {list.map(x => (
      <div>
        <input
          key={x}
          ref={el => inputRef.current[x] = el} 
          onChange={handler(x)}
          type="number"
          className="otp_box"
        />
      </div>
      ))}
    </div>
  </div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>


enter image description here

答案 1 :(得分:0)

更新:

每个数字输入都限制为单个数字。

您可以尝试以下代码:

// Example class component
class Thingy extends React.Component {
   constructor(props) {
    super(props);
    this.state = {
        focusIndex:null,
        firstDigi:null,
        secondDigi:null,
        thirdDigi:null,
        fourthDigi:null
    };
   this.ref0 = React.createRef()
   this.ref1 = React.createRef()
   this.ref2 = React.createRef()
   this.ref3 = React.createRef()
  }
  
  
  componentDidMount() {
     this.focusDiv();
  }
  
 componentDidUpdate() {
    this.focusDiv();
  }

  
  
  storeDigi=(e,index)=>{
      let valueToken = e.target.value
      if(e.target.value > 10)
      {
          valueToken = e.target.value % 10
      }
  
      switch(index)
          {
             case 1:
              this.setState({
                  focusIndex:2,
                  firstDigi:valueToken
              })
              break;
             case 2:
              this.setState({
                  focusIndex:3,
                  secondDigi:valueToken
              })
              break;
             case 3:
              this.setState({
                  focusIndex:4,
                  thirdDigi:valueToken
              })
              break;
             case 4:
              this.setState({
                  focusIndex:1,
                  fourthDigi:valueToken
              })
              break;   
          }
      
  }
  
  focusDiv=()=>{
      if(this.state.focusIndex)
      {
          console.log(this.state.focusIndex)
          switch(this.state.focusIndex)
          {
             case 1:
              this.ref0.current.focus()
              break;
             case 2:
              this.ref1.current.focus()
              break;
             case 3:
              this.ref2.current.focus()
              break;
             case 4:
              this.ref3.current.focus()
              break;    
          }
      }
  }
  
  getNumber=()=>{
     return Number(this.state.firstDigi*1000+this.state.secondDigi*100+this.state.thirdDigi*10+this.state.fourthDigi*1)
  }
  
   

  render() {
   
    return (
      <div>    
          <div style={{display:"flex"}}>
              <input type="number"  value={this.state.firstDigi} min="0" max="9" onChange={(e)=>this.storeDigi(e,1)} ref={this.ref0}/>
              <input type="number"  value={this.state.secondDigi} min="0" max="9" onChange={(e)=>this.storeDigi(e,2)} ref={this.ref1}/>
              <input type="number"  value={this.state.thirdDigi} min="0" max="9" onChange={(e)=>this.storeDigi(e,3)} ref={this.ref2}/>
              <input type="number"  value={this.state.fourthDigi} min="0" max="9" onChange={(e)=>this.storeDigi(e,4)} ref={this.ref3}/>
          </div>
          <div>{"Number : "+this.getNumber()}</div>
      </div>
    );
  }
}

// Render it
ReactDOM.render(
  <Thingy title="I'm the thingy" />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

enter image description here