我需要帮助,想知道如何使用 react-dropzone NPM 包在除图片文件 (*.png, *.jpg/jpeg, *.gif 等) 之外的文件上显示上传文件的预览。
目前,在网页表单中使用 Dropzone 上传其它类型的文件时,如果上传的是图片文件(*.png, *.jpg等),我们设置的预览就会显示一个小缩略图(见下图)。
然而,如果我上传其他类型的文件,比如 MS-Outlook 的 *.docx、*.xlsx,或 Adobe Acrobat 的 *.pdf 文件,则只会显示一个空白框和一个损坏文件的图像以及我所放置的任何alt="..."
文本,例如 "已上传文件预览" (见下图)。
我们所使用的代码几乎是直接从React Dropzon网站上的预览示例中复制过来的,因此我想知道是否有什么遗漏了呢?
我尝试过以下方法:
- 创建一个使用
react-dropzone
<Dropzone>
页面,它设置为接受任何文件类型,并使用https://react-dropzone.js.org/#previews中提供的代码进行预览,在<Dropzone>
部分的底部添加 "预览"<aside>
。 - 拖放任何类型的图像文件(*.png, *.jpg或*.jpeg、*.gif等)。
- 查看出现的预览(应该可以,是一个图像文件的缩略图)。
- 现在将任何其他类型的文件(.doc, .xls, *.pdf等)拖放到
<Dropzone>
上。 - 查看出现的该文件的预览(应该是空白并带有一个损坏文件的图像以及您所放置的任何描述文件的
alt="..."
文本)。
在文件顶部导入了 Dropzone:
import React, { Component, /* useCallback */ } from "react";
...
import Dropzone from "react-dropzone";
...
缩略图的样式/CSS代码 —
...
const thumbsContainer = {
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
marginTop: 16
};
const thumb = {
display: "inline-flex",
borderRadius: 2,
border: "1px solid #eaeaea",
marginBottom: 8,
marginRight: 8,
width: 100,
height: 100,
padding: 4,
boxSizing: "border-box"
};
const thumbInner = {
display: "flex",
minWidth: 0,
overflow: "hidden"
};
const img = {
display: "block",
width: "auto",
height: "100%"
};
...
onDrop()
回调函数——
...
onDrop = (acceptedFiles, rejectedFiles) => {
let files = acceptedFiles.map(async file => {
let data = new FormData();
data.append("file", file);
let item = await axios
.post("form/upload", data, {
headers: {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
return Object.assign(file, {
preview: URL.createObjectURL(file),
filename: response.data.filename
});
})
.catch(err => {
let rejects = rejectedFiles.map(async file => {
let data = new FormData();
await data.append("file", file);
console.log("There was an error while attempting to add your files:", err);
console.log("The files that were rejected were:\n", rejects.join('\n'));
})
});
return item;
});
Promise.all(files)
.then(completed => {
let fileNames = completed.map(function(item) {
return item["filename"];
});
this.setState({ files: completed, fileNames: fileNames });
})
.catch(err => {
console.log('DROPZONE ERROR:', err);
});
};
...
使用 <Dropzone>
的实际 JSX 代码在 React.JS 的 return()
中——
...
<Form.Field>
<label>Upload Files or Screenshots</label>
<Dropzone accept={acceptedFileTypes} onDrop={this.onDrop}>
{({ getRootProps, getInputProps, isDragActive }) => {
return (
<div
{...getRootProps()}
className={classNames("dropzone", {
"dropzone--isActive": isDragActive
})}
>
<input {...getInputProps()} />
{isDragActive ? (
<div>
<div className="centered">
<Icon name="cloud upload" size="big" />
</div>
<div className="centered">Drop Files Here.</div>
<div className="centered">
<Button className="drop-button">
Or Click to Select
</Button>
</div>
</div>
) : (
<div>
<div className="centered">
<Icon name="cloud upload" size="big" />
</div>
<div className="centered">
Drag and Drop Supporting Files here to Upload.
</div>
<div className="centered">
<Button className="drop-button">
Or Click to Select
</Button>
</div>
</div>
)}
</div>
);
}}
</Dropzone>
<aside style={thumbsContainer}>{thumbs}</aside>
</Form.Field>
...
期望的行为 —
我希望所有文件类型都能生成正确的预览。
我的设置 —
- MacBook Pro 13-Inch 2018
- 2.7 GHz Intel Core i7 处理器
- 16 GB 2133 MHz LPDDR3 RAM 内存
- MacOS 版本 10.14.4
- React 和 React-DOM 版本 16.5.2
- Node.JS 版本 10.15.2
- yarn 版本 1.15.2
- React Dropzone 版本 10.1.4
- Google Chrome for Mac OS 浏览器版本 74.0.3729.131 (Official Build) (64-bit)
- 上传到 AWS EC2 实例容器服务器。
...所以,除了图像以外的其他文件预览不起作用,这是我做错了什么吗?除了图像文件之外,这不是一个功能吗?请指导。
另外还有几个问题 —
- 如果在使用
react-dropzone
时无法为图像以外的文件生成预览,是否有一种方法可以使图像文件生成预览,而所有其他文件只列出上传的文件名等信息,就像您的React Dropzone 网站上的某些示例一样?如果有,如何在拖放文件到<Dropzone>
时在两者之间切换? - 在我们的代码中,我们几乎完全从React Dropzone 网站的示例复制了,我们发现当您将一组文件拖放到
<Dropzone>
上,然后尝试再次拖放时,会清除第一组文件并用新的文件替换它们。是否有一种方法可以让<Dropzone>
在每次拖放时累加添加文件,而不仅仅是清除以前的文件并用新的文件替换?如果有,那么请说明具体步骤。 - 如果所有其他文件都使用空白框作为文件预览,是否有一种方法可以去掉“损坏文件”的图标?
我很感激任何建设性的回复。 谢谢您提前。