I know what is wrong but don’t know how to correct this. How can I pass updated object to handler instead of inside onDrop function? I’ve looked for solution but I’m using useCallback function and I got error on every solution.
function PortfolioDropzone(params) {
const [fileList, setFileList] = useState([]);
const onDrop = useCallback((newFiles) => {
if (newFiles?.length) {
setFileList((previousFileList) => [
...previousFileList,
...newFiles.map((file) =>
Object.assign(file, { preview: URL.createObjectURL(file) })
),
]);
params.uploadHandler(fileList); // This is not working because of async of setState
}
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: { "image/*": [] },
maxSize: 1024 * 10000,
});
return (
<div className="mt-4 mb-4 border rounded p-3">
<div {...getRootProps({ className: params.className })}>
<input {...getInputProps()} />
{isDragActive ? (
<p className="m-0">Drop file ...</p>
) : (
<p className="m-0">
Drop file or click to choose file ...
</p>
)}
</div>
// some code for displaying loaded files and deleting them
</div>
);
}
export default PortfolioDropzone;
2
Answers
You can set up an effect to watch for changes in the
fileList
state and callparams.uploadHandler
when it changes.The issue you’re facing is because you are trying to pass the fileList state to params.uploadHandler(fileList) immediately after updating it within the onDrop callback. The problem is that the setFileList function is asynchronous, so the fileList may not be updated by the time you try to pass it to uploadHandler. To solve this issue, you can either use the updated fileList directly within the onDrop callback or use the useEffect hook to call params.uploadHandler after the state has been updated. I’ll provide an example of using the useEffect approach