I am trying to append file(s) to previous file state when drag and dropping image(s) to React-Dropzone library.
const [files, setFiles] = useState([])
...
const {
getRootProps,
getInputProps,
isFocused,
isDragAccept,
isDragReject,
} = useDropzone({
accept: "image/*",
onDrop: (acceptedFiles) => {
setFiles(acceptedFiles.map((file) => Object.assign(file, {
preview: URL.createObjectURL(file)
})))
}
})
In the "onDrop", I map the accepted files and append the new array using setFiles. However, using this resets the whole array and previous images are lost. I want to append the images. I've tried doing:
setFiles([...files, acceptedFiles.map((file) => Object.assign(file, {
preview: URL.createObjectURL(file)
}))])
But this returns nothing and gives me no images at all.
When appending to an array in React state it can be very convenient to use the functional update form of useState
- which is just a fancy way of saying you'll write an arrow function like this:
setFiles((oldArrayofFiles) => {
return [...oldArrayOfFiles, newFile];
})
This also prevents the problem that I think you're seeing, where because you supply onDrop
as a function, you're closing over the files
when it's still an empty array.
So in your case (and forgive me, I haven't tested this with React-Dropzone) this should work:
useDropzone({
accept: "image/*",
onDrop: (acceptedFiles) => {
setFiles((previousFiles) => {
const newFiles = acceptedFiles.map((file) => Object.assign(file, {
preview: URL.createObjectURL(file)
}));
return [...previousFiles, ...newFiles];
});
});
I might have messed up a bracket or three ... but you get the idea :-)