React JS中如何实现仅支持6位数字的OTP输入框验证
React实现6位纯数字OTP输入框的解决方案
给你几个实用的解决方案,按需选择:
方案一:type="text" + 输入过滤 + 长度限制
直接用文本输入框,在输入时过滤掉非数字字符,同时配合maxLength和JS逻辑限制长度,简单直接。
import { useState } from 'react'; function OTPInput() { const [otp, setOtp] = useState(''); const handleChange = (e) => { // 只保留数字字符 const numericValue = e.target.value.replace(/\D/g, ''); // 截断到6位,确保不会超出 setOtp(numericValue.slice(0, 6)); }; return ( <input type="text" value={otp} onChange={handleChange} maxLength={6} // 前端可视化限制,配合JS过滤更稳妥 placeholder="请输入6位OTP" /> ); }
优点:实现简单,兼容性拉满;缺点:用户输入非数字时会有瞬间显示(但会立刻被过滤)。
方案二:type="number" + 逻辑控制长度
用数字输入框,通过max属性和onChange事件限制长度,同时禁用滚轮调整避免用户误操作。
import { useState } from 'react'; function OTPInput() { const [otp, setOtp] = useState(''); const handleChange = (e) => { const value = e.target.value; // 过滤掉非数字字符,同时限制长度不超过6位 const filteredValue = value.replace(/[^0-9]/g, '').slice(0, 6); setOtp(filteredValue); }; return ( <input type="number" value={otp} onChange={handleChange} max={999999} // 6位数字最大值 onWheel={(e) => e.preventDefault()} // 禁用滚轮调整数字 placeholder="请输入6位OTP" /> ); }
优点:原生只允许输入数字(部分浏览器可能允许e、+/-,但JS会过滤);缺点:数字输入框的默认样式可能需要额外调整。
方案三:拆分单个输入框(推荐,OTP专用体验)
把6位OTP拆成6个独立的单字符输入框,每个框只能输一位数字,自动聚焦下一个,体验更符合OTP输入习惯。
import { useState, useRef } from 'react'; function OTPInput() { const [otp, setOtp] = useState(new Array(6).fill('')); const inputRefs = useRef([]); const handleChange = (index, e) => { const value = e.target.value.replace(/\D/g, ''); const newOtp = [...otp]; // 只保留一位数字 newOtp[index] = value.slice(0, 1); setOtp(newOtp); // 输入后自动聚焦下一个框(非最后一个时) if (value && index < 5) { inputRefs.current[index + 1].focus(); } }; const handleKeyDown = (index, e) => { // 退格键且当前框为空时,聚焦上一个框 if (e.key === 'Backspace' && !otp[index] && index > 0) { inputRefs.current[index - 1].focus(); } }; // 处理粘贴事件,自动填充6位数字 const handlePaste = (e) => { e.preventDefault(); const pastedValue = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, 6); if (pastedValue.length === 6) { setOtp(pastedValue.split('')); } }; return ( <div style={{ display: 'flex', gap: '8px' }}> {otp.map((digit, index) => ( <input key={index} type="text" value={digit} onChange={(e) => handleChange(index, e)} onKeyDown={(e) => handleKeyDown(index, e)} onPaste={handlePaste} maxLength={1} ref={(el) => (inputRefs.current[index] = el)} style={{ width: '40px', height: '40px', textAlign: 'center', fontSize: '18px', border: '1px solid #ddd', borderRadius: '4px' }} /> ))} </div> ); }
优点:用户体验极佳,输入反馈明确,完全杜绝非数字输入;缺点:代码量稍大,需要处理聚焦、粘贴等细节。
内容的提问来源于stack exchange,提问作者Lokesh Sharma
相关产品推荐
相关产品推荐

