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

React中使用Formik在第5个字符后添加/的实现方法

在输入内容第5个字符后自动添加/的实现方案

一、Formik 实现方案

你可以通过自定义字段的onChange事件结合Formik的setFieldValue实现自动添加/的效果,同时配合Yup的transform方法修正校验逻辑(添加/后字段长度会增加,需要先移除符号再校验原内容长度)。

完整代码示例:

import { useFormik } from 'formik';
import * as Yup from 'yup';

const NumberForm = () => {
  const formik = useFormik({
    initialValues: { number: '' },
    validationSchema: Yup.object({
      number: Yup.string()
        // 先移除所有/,再校验原内容长度
        .transform(value => value.replace(/\//g, ''))
        .min(11, "Minimum 11 characters")
        .max(11, "Maximum 11 characters") // 修正你原代码里的笔误(max写了5)
        .required("This field is required"),
    }),
    onSubmit: (values) => {
      // 提交前移除/,得到原始内容
      const rawNumber = values.number.replace(/\//g, '');
      console.log('提交的原始号码:', rawNumber);
      // 这里编写提交逻辑
    },
  });

  const handleNumberInput = (e) => {
    let inputValue = e.target.value.replace(/\//g, ''); // 先清除所有已有的/,避免重复添加
    // 当输入长度超过5时,在第5位后插入/
    if (inputValue.length > 5) {
      inputValue = `${inputValue.slice(0, 5)}/${inputValue.slice(5)}`;
    }
    // 更新Formik字段值
    formik.setFieldValue('number', inputValue);
  };

  return (
    <form onSubmit={formik.handleSubmit}>
      <input
        name="number"
        type="text"
        value={formik.values.number}
        onChange={handleNumberInput}
        placeholder="输入11位字符"
      />
      {/* 显示校验错误 */}
      {formik.touched.number && formik.errors.number && (
        <div style={{ color: 'red' }}>{formik.errors.number}</div>
      )}
      <button type="submit">提交</button>
    </form>
  );
};

export default NumberForm;

二、通用React实现方案(无需Formik)

如果不用Formik,直接用React的useState也能实现,核心逻辑和上面一致:处理输入时自动插入/,校验前移除符号。

代码示例:

import { useState } from 'react';
import * as Yup from 'yup';

const NumberForm = () => {
  const [number, setNumber] = useState('');
  const [errorMsg, setErrorMsg] = useState('');

  // 定义校验规则
  const numberSchema = Yup.string()
    .transform(v => v.replace(/\//g, ''))
    .min(11, "Minimum 11 characters")
    .max(11, "Maximum 11 characters")
    .required("This field is required");

  const handleInputChange = (e) => {
    let inputValue = e.target.value.replace(/\//g, '');
    if (inputValue.length > 5) {
      inputValue = inputValue.slice(0,5) + '/' + inputValue.slice(5);
    }
    setNumber(inputValue);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      // 执行校验
      await numberSchema.validate({ number });
      setErrorMsg('');
      // 提交前移除/
      const rawNumber = number.replace(/\//g, '');
      console.log('提交内容:', rawNumber);
    } catch (err) {
      setErrorMsg(err.message);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={number}
        onChange={handleInputChange}
        placeholder="输入11位字符"
      />
      {errorMsg && <div style={{ color: 'red' }}>{errorMsg}</div>}
      <button type="submit">提交</button>
    </form>
  );
};

export default NumberForm;

关键注意点

  1. 避免重复添加/:每次处理输入时先移除所有已有的/,再重新判断是否需要插入,这样用户删除/后也会自动恢复格式。
  2. 校验逻辑适配:因为添加/后字段长度会从11变为12,所以必须用Yup的transform方法先移除符号,再校验原始内容的长度。
  3. 提交时处理值:后端通常不需要带/的内容,所以提交前要把/移除,得到原始的11位字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:06:29