You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:43:25