React中用Formik+Yup实现输入字符串验证与转换的问题
解决Formik+Yup表单输入转换与验证问题
一、输入转换逻辑(实时处理用户输入)
先写一个工具函数,把用户输入转换成符合要求的格式:
const transformInput = (value) => { if (!value) return ''; return value .toLowerCase() // 大写转小写 .replace(/\s+/g, '-') // 空格替换为连字符 .replace(/-+/g, '-') // 合并连续的连字符(比如"test--test"转"test-test") .replace(/^-+|-+$/g, ''); // 移除首尾的连字符 };
这个函数会依次处理所有输入格式问题:比如-------test-test-test-------会转为test-test-test,Shop name123转为shop-name123,纯连字符输入会被转为空字符串。
二、在Formik中应用转换
在Formik表单里,通过自定义onChange事件实时应用转换,确保输入框的值始终是处理后的格式:
import { Formik, Form, Field } from 'formik'; import * as Yup from 'yup'; const MyForm = () => { const validationSchema = Yup.object({ username: Yup.string() .matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, '仅允许小写字母、数字和连字符,且不能全为连字符') .min(2, '长度不能少于2个字符') .max(30, '长度不能超过30个字符') .required('此字段为必填项') }); return ( <Formik initialValues={{ username: '' }} validationSchema={validationSchema} onSubmit={(values) => { console.log('提交值:', values); }} > {({ setFieldValue, values, errors, touched }) => ( <Form> <div> <label htmlFor="username">用户名</label> <Field id="username" name="username" onChange={(e) => { const transformedValue = transformInput(e.target.value); setFieldValue('username', transformedValue); }} value={values.username} /> {/* 显示错误信息 */} {errors.username && touched.username && <div style={{ color: 'red' }}>{errors.username}</div>} </div> <button type="submit">提交</button> </Form> )} </Formik> ); }; export default MyForm;
三、验证规则说明
matches(/^[a-z0-9]+(?:-[a-z0-9]+)*$/):这个正则确保输入至少包含一个字母或数字,连字符只能出现在字母/数字之间,彻底排除纯连字符、首尾连字符的无效情况。- 转换函数负责实时修正用户输入,验证规则作为兜底,防止任何不符合要求的值被提交。
额外说明
如果用户输入纯连字符,转换后会变成空字符串,此时min(2)规则会触发错误提示;如果转换后的值长度在2-30之间且符合正则,就能通过验证。
内容的提问来源于stack exchange,提问作者ganesh
相关产品推荐
相关产品推荐

