Reputation: 7543
I'm using React Dropzone (but I have the same issue in many different places). This is a function in my main component:
onDrop(images) {
this.props.dispatch(setImages(images));
this.props.images.forEach(file => {
const reader = new FileReader();
reader.onload = () => // render images
reader.onerror = () => // display error
reader.readAsDataURL(file);
});
}
The dispatch just pushes array of images to the state and then I map it to props.
Unfortunately dispatch takes some time and this.props.images
is undefined
in the example above, it works well if I put in a timeout of 2 seconds or so, but it's way too dangerous.
How can I fix that? I've tried promises but I don't know who they work and I feel like they're mostly for async requests?
Upvotes: 0
Views: 251
Reputation: 37796
FileReader is asynchronous, and not the best choice for previewing files with base64. Base64 will take up more memory and takes longer to decode/encode back and forth. Best is to create a object url instead.
If you are building a single page application and never reload the page then you should also take care of revoking it when you don't need it anymore.
you can get away with 1 of 2 asynchronous task (the other being image.onload
)
window.URL = window.URL || window.webkitURL
// Nameing convention: you are passing in files
// to the function not images, so name it 'files'
onDrop(files) {
this.props.dispatch(setImages(files))
this.props.files.forEach(file => {
const url = URL.createObjectURL(file)
// render images
})
}
Upvotes: 1