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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:20:52