You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过循环声明多个useRef变量优化OTP输入框聚焦逻辑?

优化后完整方案

1. 批量生成ref(两种可选方案)

方案A:通用兼容方案(支持动态调整OTP位数)

使用单个ref存储所有输入框的引用,避免Hook调用顺序问题:

// 初始化长度为6的引用数组,对应6位OTP输入框
const otpTextInputs = useRef(Array(6).fill(null));

方案B:固定位数场景适用

如果OTP位数固定为6,可直接生成多个ref组成的数组:

// 注意:此写法仅适用于长度固定的场景,保证Hook调用顺序不变
const otpTextInputs = Array.from({ length: 6 }, () => useRef(null));

2. 精简焦点切换逻辑

完全删除冗余的if-else判断,直接通过索引定位前一个输入框:

注:以下示例默认输入框索引从0开始计数,如果你的原有逻辑索引从1开始,把边界判断改为index > 1即可

const onOtpKeyPress = index => {
    return ({nativeEvent: {key: value}}) => {
        // 退格且当前输入框为空时跳转前一个输入框
        if (value === 'Backspace' && otpArray[index] === '') {
            // 仅当不是第一个输入框时跳转焦点
            if (index > 0) {
                // 方案A用这个写法
                otpTextInputs.current[index - 1].focus();
                // 方案B替换为下面的写法
                // otpTextInputs[index - 1].current.focus();
            }
        }
    };
};

3. 输入框绑定ref示例

如果是循环渲染输入框,直接绑定对应索引即可:

{Array.from({length: 6}).map((_, index) => (
  <TextInput
    key={index}
    // 方案A绑定写法
    ref={el => otpTextInputs.current[index] = el}
    // 方案B绑定写法
    // ref={otpTextInputs[index]}
    onKeyPress={onOtpKeyPress(index)}
    value={otpArray[index]}
    // 其他原有输入框属性保持不变
  />
))}

如果之前是手动写6个输入框,把原来的ref={firstTextInputRef}替换为对应索引的绑定即可,比如第一个输入框对应index=0,第二个对应index=1以此类推。

优化后代码完全符合DRY原则,后续如果需要调整OTP位数,只需要修改初始化时的数组长度即可,不需要逐个新增ref和判断逻辑。

内容的提问来源于stack exchange,提问作者Kerry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:12:02