0

After going through all the posts about FileReader, I've made sure I added the return statements and returned the elements after the reader onload, but still nothing shows up on the page. What else could be the problem at this point?

Code Snippet

 function showImages() {
  return Array.from(this.state.images).map(image => {
    var reader = new FileReader();
    reader.onload = function(e) {
      return <Image key={image.name} src={"data:image/png;base64," + e.target.result} />
    };
    reader.readAsDataURL(image)
  });
}
jenny
  • 191
  • 3
  • 12
  • Can you please add the code instead of image? that will help people to quickly debug. – Siva K V Jan 03 '20 at 06:07
  • you are not returning the Image component, try the below answer posted by Siva, I hope that will work – Learner Jan 03 '20 at 06:15
  • 1
    You can't have async code inside the render phase. You must render synchronously, then, in a hook (like `componentDidMount`, `useEffect` or a simple event callback), do the async tasks and save the result in the state. – Emile Bergeron Jan 03 '20 at 06:33

2 Answers2

1

As mentioned above you cannot perform async flow inside the render phase. Async action result should be resolved in triggering the component state, then the ui is rerendered.

class Images extends Component{

  state = {images: []};

  ref = React.createRef();

  showImages = () => {
  const files = this.ref.current.files;
  Array.from(files).forEach(img => {
    const reader = new FileReader();
   reader.onload = () => {
   this.setState(({images}) => ({images: [...images, reader.result]}));
  }
    reader.readAsDataURL(img);
  })
  }
  render(){
    return(
      <>
      {!!this.state.images.length && this.state.images.map(img => (<img style= 
      {{width:"auto", height:100}} src={img}/>))}
      <input type="file" multiple ref={this.ref} onChange={this.showImages}/>
      </>
    )
  }
}

see working example

gadi tzkhori
  • 574
  • 2
  • 13
-1

I think the problem is .map method still does not have any return value. The following sample code should work.

function showImages() {
  return Array.from(this.state.images).map(image => {
    let src = "";
    var reader = new FileReader();
    reader.onload = function(e) {
      src = `data:image/png;base64,${e.target.result}`;
    };
    return <Image key={image.name} src={src} />;
  });
}
Siva K V
  • 10,561
  • 2
  • 16
  • 29