反应dropzone:useState,onDropAccepted内部异步

时间:2019-09-21 12:52:24

标签: javascript reactjs

目前,我正在使用react dropzone。

在最顶部,我想跟踪用户放入放置区的文件数量。

[files, setFiles] = useState([]);

后来我有了这些:

const checkBucketLimitSingle = files => {
  if (files.length >= FILE_BUCKET_LIMIT) {
    return false;
  } else {
    return true;
  }
};

const onDropAccepted = useCallback(
  acceptedFiles => {
    // async
    const processAcceptFiles = async () => {
      let singleFile;

      singleFile = acceptedFiles[0];

      if (acceptedFiles.length > 1) {
        setIsMaxFileNum(true);
        return;
      } else {
        // e.g. api upload error
        if (isUploadError) {
          // NOTE: upload error, we empty file buckets
          // But "files" as dependency passed into useCallback, but not reflected after setFiles([])
          setFiles([]);
        }

        // check bucket limit
        const isValidBucketLimit = checkBucketLimitSingle(files);

        if (isValidBucketLimit) {
          // all good, can set
          setFiles([...files, singleFile]);
        } else {
          // go to ui
          return;
        }
      }
    };

    // fire
    processAcceptFiles();
  },
  [
    // set by useState
    files
  ]
);

const { getRootProps, getInputProps } = useDropzone({
  onDropAccepted,
  onDropRejected
});

我的用例是,在用户将文件拖放到React Drop区域后,他将单击“上传”按钮。 说上传过程有问题。 isUploadError将被设置。

我想使用setFiles([])来清理文件状态,但是files之后的const isValidBucketLimit = checkBucketLimitSingle(files)中的setFiles([])并没有反映出来

我的问题是,这是在[]之后将文件(状态)设置回setFiles([])的一种方法吗?如果仍然不清楚,我将尝试解释更多。

1 个答案:

答案 0 :(得分:0)

setFiles是异步操作,绝对不会立即以过程方式更改。

const onDropAccepted = useCallback(
  acceptedFiles => {
    // async
    const processAcceptFiles = async () => {
      let singleFile;

      singleFile = acceptedFiles[0];

      if (acceptedFiles.length > 1) {
        setIsMaxFileNum(true);
        return;
      } else {
        let updatedFiles = [...files];
        // e.g. api upload error
        if (isUploadError) {
          // NOTE: upload error, we empty file buckets
          // But "files" as dependency passed into useCallback, but not reflected after setFiles([])
          updatedFiles = [];
        }

        // check bucket limit
        const isValidBucketLimit = checkBucketLimitSingle(updatedFiles);

        return isValidBucketLimit
          ? setFiles([...updatedFiles, singleFile]);
          : setFiles([])
      }
    };

    // fire
    processAcceptFiles();
  },
  [
    // set by useState
    files
  ]
);

const { getRootProps, getInputProps } = useDropzone({
  onDropAccepted,
  onDropRejected
});

尝试一下,也许这并不是您想要的,因为对于我来说,所有东西都不清楚,您如何使用它以及尝试做什么,但是至少,它可以帮助您理解这个想法。