2

I'm trying to implement Dropzone on my app but I can't preview photos if they are drop as a multiple input. If I add them one by one it works fine but if I select multiple only the first one gets rendered.

This is my onDrop function

onDropGeneral = (currentGeneralPhoto) => {
 let index;
 for (index = 0; index < currentGeneralPhoto.length; ++index) {
  const file = currentGeneralPhoto[index];
  this.setState({
    previewGeneralPhotos: this.state.previewGeneralPhotos.concat(file)
  });
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = (event) => {
    console.log('URL: ', event.target.result);
    this.setState({
      generalPhotos: this.state.generalPhotos.concat([{ base64: event.target.result }])
    });
  };
 }
}

and this is my render method:

<h2>Dropped files</h2>
{this.state.previewGeneralPhotos.length > 0 ? <div>
  <h2>Preview {this.state.previewGeneralPhotos.length} files...</h2>
  <div>{this.state.previewGeneralPhotos.map((file) => <img src={file.preview} alt="preview failed" />)}</div>
 </div> : null}
 <h2> Upload {this.state.generalPhotos.length} Files </h2>

the Upload count is showing the right size of the array but the Preview count only counts the 1st photo dropped

1
  • Care to post you working code here? Commented Aug 2, 2018 at 17:27

1 Answer 1

1

So your issue is because setState can be asynchronous. You should use the function callback for setState as follows in your onDropGeneral function:

this.setState(({ previewGeneralPhotos }) => ({
  previewGeneralPhotos: previewGeneralPhotos.concat(file)
}))

This will make sure you don't accidentally overwrite the previous value of previewGeneralPhotos and you actually add to the existing array as you intend.

A couple of other suggestions:

  • Make sure your img elements have a key.
  • I would use an instance of the file reader for the entire Component instead of creating a new one each time your onDropGeneral method is called. You could attach an event listener for the 'load' event in componentDidMount and remove that listener in componentWillUnmount. At the very least, it's probably best to attach that event listener before calling reader.readAsDataURL.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.