如何在react-jsonschema-form的transformErrors回调中获取输入实时值
方案1:使用useRef存储实时formData(无需修改源码)
之前的写法出现滞后是因为每次渲染生成的transformErrors闭包捕获的是当前渲染周期的formData,而rjsf在校验时调用的transformErrors可能还是上一次渲染生成的版本。改用useRef存储最新的formData即可避开闭包陷阱:
import _ from 'lodash' import Form from '@rjsf/core' import { useRef, useEffect } from 'react' const WrappedForm = ({ formData, ...rest }) => { // 用ref存储最新的formData,保证永远能拿到实时值 const formDataRef = useRef(formData) useEffect(() => { formDataRef.current = formData }, [formData]) const transformErrors = (errors) => { errors.forEach(error => { if (error.name === 'format') { // 直接从ref拿最新值,不会有滞后 const value = _.get(formDataRef.current, error.property) // 错误映射逻辑 } }) return errors } return ( <Form transformErrors={transformErrors} formData={formData} {...rest} /> ) }
方案2:配置AJV将字段值注入错误参数
无需打补丁,AJV本身支持verbose配置项,开启后返回的错误对象会自带当前校验的字段值,rjsf的AJV校验器也支持传入自定义AJV实例:
import Ajv from 'ajv' import Form from '@rjsf/core' import validator from '@rjsf/validator-ajv8' // 自定义AJV实例,开启verbose模式 const customAjv = new Ajv({ verbose: true, // 核心配置,开启后错误会携带当前校验值 allErrors: true, // 其他所需AJV配置 }) // 生成自定义校验器 const customValidator = validator({ ajv: customAjv }) const WrappedForm = ({ formData, ...rest }) => { const transformErrors = (errors) => { errors.forEach(error => { if (error.name === 'format') { // 直接从错误对象取实时校验值 const value = error.rawError.data // 错误映射逻辑 } }) return errors } return ( <Form validator={customValidator} transformErrors={transformErrors} formData={formData} {...rest} /> ) }
内容的提问来源于stack exchange,提问作者Michal Kurz
相关产品推荐
相关产品推荐

