如何删除文件上传中的错误消息?

How to remove error message in file upload?

我正在使用 antd design 上传文件,这里我们只允许用户上传 JPEG 张图片。

这里我们设置规则只上传最多3JPEG张图片。

rules={[
          { required: true },
          { max: 3, message: "Only 3 attachments are allowed", type: "array" }
        ]}

问题:

这里上传3个JPEG个文件就可以了

如果我们将第 4 个文件上传为 JPEG,错误显示也没有问题。

但是当我们上传第4个文件为无效文件时,错误仍然显示哪个不正确。

重现步骤:

-> 上传 3 JPEG 个文件,

-> 上传另一种格式的第 4 个文件不是 JPEG

如果您观察结果,上传的文件将在 UI 中被忽略,但我们仍然看到错误消息 Only 3 attachments are allowed

请参阅上图以获得更好的表示效果。以 .html 格式上传第 4 个文件,因此在模式弹出窗口中出现错误,这是正确的,但规则错误消息(在最后一个文件后的文本中)仍然显示,即使 UI 中只有 3 个文件。

工作沙盒:

我看到问题可能出在 46 - 51 行,

  const normFile = (e: any) => {
    if (Array.isArray(e)) {
      return e;
    }
    return e && e.fileList;
  };

上面那行returns上传的文件即使超过限制也被隐藏了。

请帮助我解决上述问题,因为我被困了很长时间,在此先感谢您。

问题是,即使您在 UI 中看到了三个文件,但错误出现在文件下方,因为您使用的是 antd 形式和任何用 包装并带有 name属性,由antd表单控制。通过将 fileList 状态传递给上传组件,这并不意味着您正在控制文件列表并且您正好有 3 个文件。为了证明这一点,让我举个例子:

1. 上传 3 个 jpeg 文件并使用 form.getFieldValue('attachment') 获取附件的值。 预期结果:一个包含 3 个文件的数组,文件下方没有错误

2. 再上传一张 jpeg 或任何文件并用 form.getFieldValue('attachment') 检查附件值 预期结果: 一个长度为 4 的文件数组,根据您的要求,它应该是 3 files。还有一个不会消失的错误。

你的代码有两个问题。
问题 1: 正如您所说,如果您在上传 3 个 jpeg 文件后上传 4 个 jpeg 文件,我仍然在 UI 中看到 4 个文件。
解决方案: 如果它已经有 3 个文件,请不要在 fileList 中添加更多文件。在 beforeUpload 中,将 setFileList((prev) => [...prev, file]); 替换为以下代码:

setFileList((prev) => {
    if (prev.length < 3) {
        return [...prev, file];
    }
    return prev;
});

第二个问题: 即使您在 UI.
中有 3 个文件,错误也不会消失 解决方法:可以使用onChange函数。您可以检查 info .fileList 的长度是否大于 3,然后只需将表单附件值替换为原始 fileList。我设置了超时显示错误,你可以上传3个附件,2秒后删除错误信息。

onChange: (info) => {
    if (info.fileList.length > 3) {
        setTimeout(() => form.setFieldsValue({ attachment: fileList as any }), 2000);
    }
}

希望这能解决您的问题。

完整代码

import { useState, useMemo } from 'react';
import { Upload, Button, message, Form } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { UploadFile, UploadProps } from 'antd/lib/upload/interface';
import { RcFile } from 'rc-upload/lib/interface';

interface FormRule {
    title: string;
    attachment?: { file: RcFile; fileList: RcFile[] };
}

const Uploader = () => {
    const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
    const [form] = Form.useForm<FormRule>();

    const validateFileType = ({ type, name }: UploadFile, allowedTypes: string[] = ['image/jpeg']) => {
        return allowedTypes.includes(type!);
    };

    const uploadProps = useMemo(
        () =>
            ({
                multiple: true,
                beforeUpload: (file: UploadFile) => {
                    const isAllowedType = validateFileType(file);
                    if (!isAllowedType) {
                        message.error(`${file.name} is not JPEG file`);
                        return false;
                    }
                    setFileList((prev) => {
                        if (prev.length < 3) {
                            return [...prev, file];
                        }
                        return prev;
                    });
                    return false;
                },
                onRemove: (file: UploadFile) => {
                    setFileList((prev) => prev.filter((item) => item.uid !== file.uid));
                },
                onChange: (info) => {
                    if (info.fileList.length > 3) {
                        setTimeout(() => form.setFieldsValue({ attachment: fileList as any }), 2000);
                    }
                }
            } as UploadProps),
        [fileList]
    );

    const onSubmit = async (data: FormRule) => {
        console.log('data');
    };

    const normFile = (e: any) => {
        if (Array.isArray(e)) {
            return e;
        }
        return e && e.fileList;
    };

    return (
        <Form form={form} onFinish={onSubmit} layout='vertical'>
            <Form.Item
                name='attachment'
                valuePropName='attachment'
                getValueFromEvent={normFile}
                rules={[{ required: true }, { max: 3, message: 'Only 3 attachments are allowed', type: 'array' }]}
            >
                <Upload {...uploadProps} fileList={fileList}>
                    <Button icon={<UploadOutlined />}>Upload JPEG only</Button>
                </Upload>
            </Form.Item>

            <Button type='primary' htmlType='submit'>
                Submit
            </Button>
        </Form>
    );
};

export default Uploader;