React中useRef聚焦失效问题:输入框自动跳转焦点需求实现
解决方案:React实现输入后自动聚焦下一个输入框
你的代码存在几处关键问题导致自动聚焦失效,以下是修正后的完整方案:
问题分析
- Ref使用错误:React的
useRef需要通过.current属性存储和访问引用,你直接给itemsRef[0]赋值,并未将输入框引用存入持久化的ref容器中。 - 聚焦目标错误:你尝试调用
ref[i].focus(),但此处ref未定义,正确操作应是获取下一个输入框的引用itemsRef.current[i+1]。 - 受控组件处理不当:空的
onChange回调无意义,还可能引发警告,需正确实现受控组件逻辑。
修正后的代码
<html> <head> <title>React App</title> <script src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script> </head> <body> <div id="mydiv"></div> <script type="text/babel"> function Inputs() { const [otp, setOtp] = React.useState(['', '', '']); // 初始化对应输入框数量的状态 const itemsRef = React.useRef([]); // 存储输入框引用的容器 const handleKeyPress = (e, i) => { const key = e.key; // 只处理数字键 if (!isNaN(parseInt(key))) { const newOtp = [...otp]; newOtp[i] = key; setOtp(newOtp); // 如果不是最后一个输入框,聚焦下一个 if (i < itemsRef.current.length - 1) { itemsRef.current[i + 1]?.focus(); } } // 处理退格键,回到上一个输入框 else if (key === 'Backspace' && i > 0) { const newOtp = [...otp]; newOtp[i] = ''; setOtp(newOtp); itemsRef.current[i - 1]?.focus(); } }; // 统一渲染输入框,避免重复代码 const renderInputs = () => { return otp.map((value, index) => ( <input key={index} placeholder={`input ${index + 1}`} type="number" className="otpNumber" onChange={(e) => { // 受控组件的onChange,更新对应位置的状态 const newOtp = [...otp]; newOtp[index] = e.target.value; setOtp(newOtp); }} onKeyPress={(e) => handleKeyPress(e, index)} ref={(el) => (itemsRef.current[index] = el)} autoFocus={index === 0} value={value} maxLength={1} // 限制只输入一个字符 /> )); }; return ( <div className="space-x-2"> {renderInputs()} <p>输入数字后会自动聚焦下一个输入框,退格会回到上一个</p> </div> ); } ReactDOM.render(<Inputs />, document.getElementById("mydiv")); </script> </body> </html>
关键修正点
- 正确使用useRef:将输入框引用存入
itemsRef.current数组,确保组件重渲染后引用不丢失。 - 聚焦逻辑修正:通过
itemsRef.current[i+1]?.focus()获取并聚焦下一个输入框,用可选链避免越界报错。 - 优化受控组件:实现正确的
onChange回调,添加maxLength={1}限制每个输入框只输入一个字符,适配OTP输入场景。 - 增加退格处理:补充退格键逻辑,提升用户操作体验。
- 代码复用:用
map渲染输入框,减少重复代码,便于后续扩展输入框数量。
内容的提问来源于stack exchange,提问作者Jannik Stach
相关产品推荐
相关产品推荐

