React-dropzone,如何告诉用户文件的maxSize太大了?

时间:2017-06-26 01:11:44

标签: reactjs react-redux react-dropzone

我使用以下内容允许用户使用react-dropzone上传个人资料照片:

const FILE_FIELD_NAME = 'files';

const renderDropzoneInput = (field) => {
  const files = field.input.value;
  let dropzoneRef;
  return (
    <div>
      <Dropzone
        name={field.name}
        onDrop={( filesToUpload, e ) => field.input.onChange(filesToUpload)}
        ref={(node) => { dropzoneRef = node; }}
        accept="image/jpeg, image/png"
        maxSize={5242880}
      >
        {({ isDragActive, isDragReject, acceptedFiles, rejectedFiles }) => {
          if (isDragActive) {
            return "This file is authorized";
          }
          if (isDragReject) {
            return "This file is not authorized";
          }
          return acceptedFiles.length || rejectedFiles.length
            ? `Accepted ${acceptedFiles.length}, rejected ${rejectedFiles.length} files`
            : "Try dropping some files.";
        }}
      </Dropzone>

      <button type="button" onClick={() => { dropzoneRef.open() }}>Open File Dialog</button>

      {field.meta.touched &&
        field.meta.error &&
        <span className="error">{field.meta.error}</span>}
      {
        files && Array.isArray(files) && (
        <ul>
          { files.map((file, i) =>
            <li key={i}>
              <img key={i} style={{width: 50, height: 50}} src={file.preview} alt="preview" />
              {file.name}
            </li>
          )}
        </ul>
      )}
    </div>
  );
}

...在我的redux-form中:

    <div>
      <label htmlFor={FILE_FIELD_NAME}>Files</label>
      <Field
        name={FILE_FIELD_NAME}
        component={renderDropzoneInput}
      />
    </div>

React-dropzone目前正在尊重maxSize,它拒绝超过5megs的文件......问题是react-dropzone没有告诉用户文件太大。

如何更新上述内容以告知用户文件是否超过允许的maxSize?谢谢!

2 个答案:

答案 0 :(得分:0)

加载后,您可以为每个文件设置当前大小,并与常量进行比较。我不知道文件是否有大小道具,但我认为它包含在道具中。代码应如下所示:

const FILE_FIELD_NAME = 'files';

const ErrorMessage = ({ children }) => (
  <div
    style={{
      fontStyle: 'italic',
      color: 'red',
      }}
    >
    {children}
  </div>
)

const renderDropzoneInput = (field) => {
  const files = field.input.value;
  let dropzoneRef;
  const MAX_SIZE = 5242880;
  return (
    <div>
      <Dropzone
        name={field.name}
        onDrop={( filesToUpload, e ) => field.input.onChange(filesToUpload)}
        ref={(node) => { dropzoneRef = node; }}
        accept="image/jpeg, image/png"
        maxSize={MAX_SIZE}
      >
        {({ isDragActive, isDragReject, acceptedFiles, rejectedFiles }) => {
          if (isDragActive) {
            return "This file is authorized";
          }
          if (isDragReject) {
            return "This file is not authorized";
          }
          return acceptedFiles.length || rejectedFiles.length
            ? `Accepted ${acceptedFiles.length}, rejected ${rejectedFiles.length} files`
            : "Try dropping some files.";
        }}
      </Dropzone>

      <button type="button" onClick={() => { dropzoneRef.open() }}>Open File Dialog</button>

      {field.meta.touched &&
        field.meta.error &&
        <span className="error">{field.meta.error}</span>}
      {
        files && Array.isArray(files) && (
        <ul>
          { files.map((file, i) =>
            <li key={i}>
              {file.size > MAX_SIZE ?  (
                  <ErrorMessage>
                    {'file is too big, try with another file'}
                    {file.name}
                  </ErrorMessage>
                ) : (
                  <React.fragment>
                    <img key={i} style={{width: 50, height: 50}} src={file.preview} alt="preview" />
                    {file.name}
                  </React.fragment>
                ) 
              }
            </li>
          )}
        </ul>
      )}
    </div>
  );
}

答案 1 :(得分:0)

import React, { useState } from "react";
import { useDropzone } from "react-dropzone";

const UploadFile = () => {
  const [errors, setErrors] = useState("");

  const { getRootProps, getInputProps } = useDropzone({
    multiple: false,
    onDrop: (acceptedFiles, fileRejections) => {
      fileRejections.forEach((file) => {
        file.errors.forEach((err) => {
          if (err.code === "file-too-large") {
            setErrors(`Error: ${err.message}`);
          }

          if (err.code === "file-invalid-type") {
            setErrors(`Error: ${err.message}`);
          }
        });
      });
    }

  return (
    <div{...getRootProps()}>
      <input {...getInputProps()} title={title} />
        <p style={{ color: "red", padding: 5, margin: 0, fontSize: 14 }}>
          {errors}
        </p>
    </div>
  );
};
  1. 为上述错误创建useState。

  2. onDrop提供了第二个数组参数“ fileRejections”。

  3. 遍历fileRejections以访问其中的错误数组。

  4. 然后,遍历errors数组以访问“代码和消息”。

  5. 检查错误代码是否为“文件太大”或“文件无效类型”。哪些是最常见的错误代码。

  6. 在if else块中使用setState将err.message设置为错误状态。

  7. 在dropzone的主要div内的“ p”标签中显示错误状态。

当多个设置为“ false”时,此方法效果很好。对于多个文件错误,您将不得不使用arrayState。我还没有真正调查过。