如何在React Bootstrap V3中用多个refs实现输入框焦点自动切换?
解决React Bootstrap V3中OTP输入框焦点自动切换问题
问题分析
你当前的代码中,inputControlRef是单个变量,每次赋值都会被最后一个输入框的引用覆盖;直接尝试用this.inputControlRef[0]赋值时,因为未初始化inputControlRef为数组,导致出现Uncaught TypeError: Cannot set properties of undefined (setting '0')错误。
实现步骤
- 初始化Ref数组:在组件构造函数中创建数组,用于存储多个输入框的DOM引用
- 绑定输入框Ref:通过
inputRef将每个输入框的引用存入数组对应索引位置 - 实现焦点切换逻辑:输入内容后自动聚焦下一个输入框;退格且当前输入框为空时,聚焦上一个输入框
- 限制输入长度:确保每个输入框仅能输入1个字符,避免多字符干扰焦点逻辑
完整代码示例
export default class OtpInput extends React.PureComponent { constructor(props) { super(props); this.state = { otp: "" }; // 初始化存储输入框ref的数组 this.inputControlRefs = []; } // 处理输入框内容变更 handleOtpChange = (index, e) => { const { value } = e.target; // 只保留最后一个输入的字符,限制单框输入长度 const singleChar = value.slice(-1); const newOtpArray = [...this.state.otp]; newOtpArray[index] = singleChar; this.setState({ otp: newOtpArray.join("") }, () => { // 输入完成后,自动聚焦到下一个输入框(如果存在) if (singleChar && index < this.inputControlRefs.length - 1) { this.inputControlRefs[index + 1].focus(); } }); }; // 处理退格键逻辑,回到上一个输入框 handleKeyDown = (index, e) => { if (e.key === "Backspace" && !this.state.otp[index] && index > 0) { this.inputControlRefs[index - 1].focus(); } }; render() { // 可根据需求调整OTP输入框数量 const otpLength = 4; return ( <form className="otpInput"> <Row> {Array.from({ length: otpLength }).map((_, index) => ( <Col xs={2} key={index}> <FormGroup controlId={`otpInput${index + 1}`}> <FormControl inputRef={(ref) => { this.inputControlRefs[index] = ref; }} type="text" maxLength={1} value={this.state.otp[index] || ""} onChange={(e) => this.handleOtpChange(index, e)} onKeyDown={(e) => this.handleKeyDown(index, e)} /> </FormGroup> </Col> ))} </Row> </form> ); } }
关键说明
- Ref数组初始化:在
constructor中声明this.inputControlRefs = [],确保可以通过索引存储每个输入框的DOM引用 - 输入限制:通过
maxLength={1}属性和value.slice(-1)处理,保证每个输入框仅保留1个字符 - 动态生成输入框:用
Array.from动态生成指定数量的输入框,便于后续调整OTP长度 - 焦点切换:输入字符后自动跳转下一个输入框;退格且当前框为空时,自动回到上一个输入框,提升用户体验
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

