我有一个组件,用户可以在其中拖动一些文件并将其存储在状态中。没有进入大部分代码,这就是我所拥有的
const [files, setFiles] = useState([]);
useEffect(() => {
setFiles(getFileList(files, acceptedFiles));
}, [files, acceptedFiles]);
我正在使用 React Dropzone 包,当用户将文件放入容器时,dropzone 的 acceptedFiles 属性会填充这些文件。在 useEffect 钩子中,我想根据这些新文件设置我的状态 files,即每当用户添加新文件时,我想更新我的状态以包含这些新文件并触发重新渲染。然而,这并没有发生。当我放下一个文件时,没有任何东西被渲染。但是当我删除另一个文件时,第一个文件被渲染,当我添加第三个文件时,第二个文件被渲染等等......我不确定我做错了什么,有什么建议吗?
这是我的组件:
export function Upload() {
const { acceptedFiles, getRootProps, getInputProps, isDragActive, open } =
useDropzone({ noClick: true });
const [files, setFiles] = useState([]);
useEffect(() => {
setFiles(getFileList(files, acceptedFiles));
}, [files, acceptedFiles]);
const baseContent = (
<div className={styles.baseContent}>
<h4 className={styles.uploadText}>{"click to add or drop files here"}</h4>
<AiOutlineUpload className={styles.icon} />
</div>
);
return (
<Dropzone getRootProps={getRootProps} isDragActive={isDragActive}>
{files.length === 0 ? (
<Clickzone getInputProps={getInputProps} open={open}>
{baseContent}
</Clickzone>
) : (
<FileSystem files={files} getInputProps={getInputProps} open={open} />
)}
</Dropzone>
);
}
function getFileList(files, newFiles) {
var totalSize = getTotalSize(files);
var count = files.length;
for (var i = 0; i < newFiles.length; i++) {
if (count >= constants.MAX_NUM_OF_FILES) break;
var file = {
name: newFiles[i].name,
type: newFiles[i].type,
size: newFiles[i].size,
};
file.name = sanitizeFileName(file.name);
file.size = convertToMB(file.size);
if (file.size > constants.MAX_UPLOAD_SIZE) continue;
totalSize += file.size;
if (totalSize > constants.MAX_UPLOAD_SIZE) break;
count++;
files.push(file);
}
return files;
}
答案 0 :(得分:1)
目前您的 useEffect 正在等待文件和接受的文件运行。这实际上会导致无限循环,因为您更改文件会导致 useEffect 运行然后设置文件。
您应该做的是使用 onDrop 事件并在删除文件后调用该函数。
像这样
export function Upload() {
const { acceptedFiles, getRootProps, getInputProps, isDragActive, open } =
useDropzone({ noClick: true });
const [files, setFiles] = useState([]);
const baseContent = (
<div className={styles.baseContent}>
<h4 className={styles.uploadText}>{"click to add or drop files here"}</h4>
<AiOutlineUpload className={styles.icon} />
</div>
);
const onDropAccepted = (acceptedFiles) => {
setFiles(acceptedFiles)
}
return (
<Dropzone getRootProps={getRootProps} isDragActive={isDragActive} onDrop={handleInDropAccepted}>
{files.length === 0 ? (
<Clickzone getInputProps={getInputProps} open={open}>
{baseContent}
</Clickzone>
) : (
<FileSystem files={files} getInputProps={getInputProps} open={open} />
)}
</Dropzone>
);
}
这是文档的链接,其中显示了您可以添加的所有其他道具,https://react-dropzone.js.org/#!/Dropzone