如何在React-Hook-Form中不借助第三方库实现文件大小验证
React-Hook-Form 无第三方库实现文件大小+类型验证
完全可以不依赖Yup、Zod等验证库,直接在自定义验证函数中同时实现文件类型和大小验证。不过需要先修正原代码中文件对象获取的问题——原代码里的文件输入框没有正确绑定React-Hook-Form的field属性,导致拿到的只是文件路径字符串而非真实的File对象,无法直接读取文件大小。
以下是修正并添加大小验证后的完整代码:
import { Controller, useForm } from "react-hook-form"; import { FormControl, FormHelperText, FormLabel, Button, Box } from "@mui/material"; // 假设你使用MUI组件 export const Demo = () => { const { control, formState: { errors } } = useForm({ defaultValues: { file: null, } }); const validateFile = (file) => { // 验证文件类型 const allowedTypes = ['application/pdf', 'image/gif', 'image/jpeg', 'image/png', 'image/tiff']; if (!allowedTypes.includes(file.type)) { return "Please upload a pdf, gif, jpeg, png or tiff file."; } // 验证文件大小:10MB = 10 * 1024 * 1024 字节 const maxSize = 10 * 1024 * 1024; if (file.size > maxSize) { return "File size must be less than 10MB."; } }; return ( <form> <Controller name="file" control={control} rules={{ required: 'File is required.', validate: validateFile, }} render={({ field }) => ( <FormControl error={!!errors.file}> <Box> <Button component="label" variant="contained" > File Upload <input hidden type="file" accept=".pdf,image/gif,image/jpeg,image/png,image/tiff" onChange={(e) => field.onChange(e.target.files[0])} // 传递真实的File对象 value={field.value?.name || ''} // file input的value需为字符串,这里用文件名或空值 /> </Button> {/* 显示已选文件名 */} {field.value && <FormLabel sx={{ pl: 1 }}>{field.value.name}</FormLabel>} </Box> <FormHelperText>{errors.file?.message}</FormHelperText> </FormControl> )} /> </form> ) }
关键修改说明:
- 修复文件对象传递:给文件输入框添加
onChange,将选中的File对象(e.target.files[0])传给field.onChange,让React-Hook-Form拿到真实文件对象用于验证。 - 类型验证优化:直接使用File对象的
type属性判断类型,比解析文件名后缀更可靠。 - 添加大小验证:定义10MB对应的字节数上限,通过File对象的
size属性判断是否超限,返回对应错误提示。 - 文件名显示修正:通过
field.value?.name直接获取文件名,无需解析路径字符串。
内容的提问来源于stack exchange,提问作者190303458
相关产品推荐
相关产品推荐

