I have made an example but cannot figure out the issue. in App.tsx Upload function the state myfiles.length is always zero even though in the main component you can see the file array does get updated properly. I thought it was a scope issue so I changed to an arrow function but still the same behaviour. App.tsx:
import { createRef, useState } from 'react';
import './App.css';
import FileUploadWidgetDropzone from './FileUploadWidgetDropzone';
import { DropzoneRef } from 'react-dropzone';
import { IconButton } from '@mui/material';
import { AttachFile } from "@mui/icons-material";
function App() {
const [myfiles, setMyFiles] = useState<File[]>([]);
const dropzoneRef = createRef<DropzoneRef>();
function openDialog(): void {
if (dropzoneRef) {
dropzoneRef.current?.open();
}
}
function removeFile(file: File) {
const newFiles = [...myfiles];
newFiles.splice(newFiles.indexOf(file), 1);
setMyFiles(newFiles);
if (myfiles.length <= 4) {
}
}
const uploadFiles = (files: File[]) => {
debugger;
//LENGTH on myfiles is always zero
if (myfiles.length > 4) {
console.log("ERROR TOO MANY FILEs")
}
// but this works correctly
setMyFiles((prevState) => [...prevState, ...files]);
}
return (
<div className="App">
<h2> boom</h2>
<IconButton aria-label="delete" onClick={openDialog}>
<AttachFile sx={{ transform: "rotate(45deg)", width: "2rem", height: "2rem" }} />
</IconButton>
<FileUploadWidgetDropzone
acceptFiles={{
"image/*": [],
"application/msword": [],
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": [],
}}
removeFile={removeFile}
uploadFiles={uploadFiles}
uploadedFiles={myfiles}
maxFilesAllowed={4}
ref={dropzoneRef}
/>
</div>
);
}
export default App;
FileUploadWidgetDropzone:
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import { Typography } from "@mui/material";
import React, { memo, useCallback } from "react";
import Dropzone, { Accept, DropzoneRef } from "react-dropzone";
import UploadedFileItem from "./UploadedFileItem";
interface Props {
uploadedFiles: File[];
removeFile: (file: File) => void;
uploadFiles: (files: File[]) => void;
acceptFiles?: Accept;
maxFilesAllowed?: number;
}
const FileUploadWidgetDropzone = React.forwardRef<DropzoneRef, Props>(
({ uploadFiles, uploadedFiles, removeFile, acceptFiles, maxFilesAllowed }, ref) => {
const dzStyles = {
display: "none",
};
const onDrop = useCallback((acceptedFiles: any) => {
debugger;
uploadFiles(acceptedFiles);
}, []);
return (
<Dropzone
ref={ref}
maxFiles={maxFilesAllowed}
noClick
noKeyboard
onDrop={onDrop}
accept={acceptFiles ? acceptFiles : { "image/*": [] }}
>
{({ getRootProps, getInputProps, acceptedFiles, isDragActive }) => {
return (
<>
<div {...getRootProps()} style={isDragActive ? { ...dzStyles } : dzStyles}>
<input {...getInputProps()} />
<CloudUploadIcon />
<Typography variant="body2" color="text.secondary">
Drop file here or
</Typography>
</div>
{uploadedFiles.map((file: File, index:number) => (
<UploadedFileItem isLoaded={false} fileName={file.name} onRemove={removeFile} key={index}/>
))}
</>
);
}}
</Dropzone>
);
}
);
export default memo(FileUploadWidgetDropzone);
Full code example: https://codesandbox.io/s/heuristic-breeze-xz5whf?file=/src/App.tsx