I have been trying to push secure_urls from Cloudinary data response to React state Array with no success. When I add a new Image to the dropzoneArea, the previous urls are added to the array, hence duplicating urls. Does anyone have an idea how to approach this?
State
const [fileItems, setFileItems] = useState([]);
DropZone
<DropzoneArea
acceptedFiles={["image/jpeg", "image/png", "image/bmp", "image/jpg"]}
onChange={handleFiles}
onDelete={handleDeleteFile}
showFileNames
filesLimit={5}
/>
const handleFiles = (files) => {
files.forEach((file) => {
const formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", process.env.REACT_APP_UPLOAD_PRESET);
return Axios.post(
`https://api.cloudinary.com/v1_1/${process.env.REACT_APP_CLOUD_NAME}/upload`,
formData,
{
headers: { "X-Requested-With": "XMLHttpRequest" },
}
)
.then((res) => {
const fileUrls = res.data.secure_url;
setFileItems(fileItems=>[...fileItems,fileUrls])
})
.catch((err) => {
console.log(err.message);
});
});
};
I see multiple problems with your code. For starters, you have a shadowed variable name, see the duplication of fileItems
const [fileItems, setFileItems] = useState([]);
...
setFileItems(fileItems=>[...fileItems,fileUrls])
Also, calling setState inside a loop is an anti-pattern. You could try to refactor your code something like this:
const handleFiles = (files) => {
const fileUrlArray = [];
files.forEach((file) => {
const formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", process.env.REACT_APP_UPLOAD_PRESET);
return Axios.post(
`https://api.cloudinary.com/v1_1/${process.env.REACT_APP_CLOUD_NAME}/upload`,
formData,
{
headers: { "X-Requested-With": "XMLHttpRequest" },
}
)
.then((res) => {
const fileUrls = res.data.secure_url;
fileUrlArray.push(fileUrls);
})
.catch((err) => {
console.log(err.message);
});
});
setFileItems(prevState => [...prevState, ...fileUrlArray])
};
Not sure if it'll fix your code, but this is something to start on.