React Bootstrap表单正则验证失效问题求助
问题解决:React-bootstrap + React-Hook-Form 正则验证不生效 & 输入值无法跟踪
核心问题分析
- 受控状态被破坏:手动给
Form.Control设置了value={value},但fieldInfo里未传递value,导致值始终为undefined。更关键的是,React-Hook-Form的register会自动绑定控件的value和onChange,手动设置value会覆盖这个机制,直接导致onChange不触发,输入值完全无法跟踪。 - 正则规则格式错误:传给
register的pattern.value是字符串格式的正则(比如"^[0-9]{8,12}$"),但React-Hook-Form要求pattern的value必须是RegExp对象,字符串格式的正则会被忽略,导致验证不生效。 - 冗余自定义验证:手写的
validatePattern完全没必要,register已经内置了pattern验证逻辑,额外设置isValid反而可能干扰原生验证流程。
修正后的TextInput组件代码
import { Form, Col } from 'react-bootstrap'; const TextInput = (props) => { const { type, colProps, register, errors, fieldInfo, ...restProps } = props; const { label, name, validation, defaultValue = '' } = fieldInfo || {}; // 将字符串格式的正则转成RegExp对象 const processedValidation = { ...validation }; if (processedValidation?.pattern?.value) { processedValidation.pattern = { ...processedValidation.pattern, value: new RegExp(processedValidation.pattern.value) }; } return ( <Form.Group as={Col} {...colProps}> {label} <Form.Control type={type || 'text'} name={name} defaultValue={defaultValue} {...restProps} {...register(name, processedValidation)} // 用React-Hook-Form的errors对象控制验证状态 isValid={!errors[name]} isInvalid={!!errors[name]} /> {/* 显示错误提示 */} {errors[name] && <Form.Control.Feedback type="invalid"> {errors[name].message} </Form.Control.Feedback>} </Form.Group> ); }; export default TextInput;
关键修改点说明
- 移除手动
value绑定:让React-Hook-Form完全接管控件的受控状态,onChange会正常触发,输入值能被正确跟踪。 - 正则格式转换:在传递给
register前,把字符串正则转成RegExp对象,确保pattern验证规则被React-Hook-Form识别。 - 使用原生错误状态:通过
errors对象(来自React-Hook-Form的useForm返回值)控制isValid和isInvalid,同时添加错误提示组件,让验证结果可视化。 - 简化默认值处理:直接从
fieldInfo取默认值,避免冗余的三元判断。
验证JSON配置无需修改
你的JSON配置可以继续使用,组件会自动处理正则格式转换:
{ "type": "TEXT_INPUT", "colProps": { "sm":"auto" }, "fieldInfo": { "label": "Case Number", "name": "caseNumber", "validation" :{ "pattern": { "value": "^[0-9]{8,12}$", "message": "Input is Numeric, larger than 8, less than 13" }, "required": { "value": true, "message": "Case number is required" }, "maxLength": { "value": 12, "message": "Case number should be less than 13 chars." } } } }
父组件使用示例
确保父组件正确传递React-Hook-Form的register和errors对象:
import { useForm } from 'react-hook-form'; import TextInput from './TextInput'; import fieldConfig from './fieldConfig.json'; const ParentForm = () => { const { register, formState: { errors } } = useForm(); return ( <Form> <TextInput type={fieldConfig.type} colProps={fieldConfig.colProps} fieldInfo={fieldConfig.fieldInfo} register={register} errors={errors} /> </Form> ); };
内容的提问来源于stack exchange,提问作者iowatiger08
相关产品推荐
相关产品推荐

