React中使用Formik实现父组件对子组件文件上传校验
Formik文件上传组件文件名特殊字符校验实现方案
核心逻辑保持你现有「父层validationSchema统一管控所有校验规则」的架构不变,同时实现文件上传(含点击选择、拖拽两种场景)瞬间实时展示错误提示,不需要额外新增独立的错误状态。
步骤1:在全局校验Schema中补充文件名校验规则
首先把文件名合法性规则写入父层的OrderValidationSchema,保证提交时的全局拦截逻辑统一。
注意:把文件名校验的正则抽成公共常量,后续Schema和上传组件共用,避免两处规则不一致。
// 公共常量文件中定义,按需调整你需要拦截的特殊字符范围 export const VALID_FILENAME_REGEX = /^[a-zA-Z0-9_\-\u4e00-\u9fa5.]+$/; // 示例规则:仅允许中英文、数字、下划线、横杠、英文点 // OrderValidationSchema中补充对应字段校验 const OrderValidationSchema = Yup.object().shape({ // 原有其他字段的校验规则完全保留 // ... [OrderForm.formField.orderFilesFe.name]: Yup.array() .of( Yup.mixed().test( 'is-valid-filename', 'Invalid file name', (file) => { // 标记为已删除的文件跳过校验 if (!file || file.delete) return true; return VALID_FILENAME_REGEX.test(file.name); } ) ) // 原有该字段的其他校验规则(比如必填)保留即可 });
步骤2:修改上传组件的上传逻辑,上传即触发校验
你的上传组件不管是点击选择文件、还是拖拽上传,最终都会走uploadFiles方法,只需要修改这一个方法即可覆盖所有上传场景:
- 上传前先过滤掉文件名不符合规则的文件
- 主动标记字段为已触碰(touched),触发现有错误提示逻辑
- 仅把合法文件加入上传列表
修改后的uploadFiles方法代码如下:
// 注意从公共常量文件引入刚才定义的VALID_FILENAME_REGEX import { VALID_FILENAME_REGEX } from '@/constants'; const uploadFiles = async (fileList: File[]) => { setIsLoading(true) try { if (!fileList) { setIsLoading(false) return } let existingFiles = files == null ? [] : files let newList = [...existingFiles] const invalidFileNames: string[] = [] const validFiles: File[] = [] // 先拆分合法/非法文件 Array.from(fileList).forEach((newFile) => { if (!VALID_FILENAME_REGEX.test(newFile.name)) { invalidFileNames.push(newFile.name) return } validFiles.push(newFile) }) // 存在非法文件时,主动触发字段touched状态,展示错误提示 if (invalidFileNames.length > 0) { helpers.setTouched(true, true) // 可选:增加轻提示告知用户哪些文件被拦截,比如用项目里的toast组件 // toast.error(`文件名包含特殊字符,以下文件无法上传:${invalidFileNames.join('、')}`) } // 仅将合法文件加入列表 validFiles.forEach((newFile) => { let index = newList.findIndex((t) => t.name == newFile.name) if (index > -1) { newList[index]['delete'] = false } else { newList.push(newFile) } }) onFilesUploadedFn(newList) setIsLoading(false) } catch (error) { alert(error) setIsLoading(false) } }
方案适配说明
- 你现有组件已经实现了
meta.touched && meta.error时展示错误文案、上传框变红边框的逻辑,调用helpers.setTouched(true)后会直接复用这套逻辑,不需要额外写样式或错误状态管理 - 非法文件会被直接拦截,不会出现在已上传列表中,避免用户误以为上传成功
- 全局提交时的校验逻辑自动生效,不需要额外处理提交拦截
- 规则统一维护在公共常量+Yup Schema中,后续调整特殊字符拦截范围只需要改一处
内容的提问来源于stack exchange,提问作者Ashar
相关产品推荐
相关产品推荐

