1

I'm having trouble setting the state with FileReader's onLoad. The goal is to display multiple images and update the state.

I have read nearly all of the stackoverflow posts and I have tried my best to familiarize myself with the File/FileReader API. Yet, when I try to update my state- the React Developer Tools doesn't have by state updating.

I expect to see two photos on my page and my photoList state to be updated, however, it's not showing up.

class App extends Component{ constructor() { super(); this.state = { photoList: [] }; } onSelectFile = event => { event.preventDefault(); const { photoList } = this.state; const { imageFile } = event.target; for( let i = 0; i < imageFile; i++){ let reader = new FileReader(); let file = imageFile[i] reader.onload = (e) => { const { result } = e.target this.setState({ photoList: [...photoList, result] }) } reader.readAsDataURL(file) } } render() { const { photoList } = this.state; return ( <div> <input type="file" accept="image/jpeg, image/png" multiple onChange={this.onSelectFile} /> <img src={ photoList } alt=""/> </div> ); } } 

2 Answers 2

1

TLDR, working example there

That is the list of fixes and improvements, what I found when reviewing your code:
1. You need to get props in the constructor and pass to super, if you inherited from React.Component
2. imageFile not correct property in event.target, instead of this you should use files which will contain updated files, and loop through files array

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply 1.) I was under the impression that I could name the property attached to event.property anything that I wanted and that is why I named it imageFile. 2.) I was able to update the state, however, if I select multiple photos, only one shows up. Is this because setState should not be in a for-loop?
ahhhhh yea... you know a lot of the stackoverflow answers have setState within the loop. I've found myself thinking- FileReader is executed in an async way. I would have to create a Promise that when resolved, would have to pass it's values (outside of it's for loop scope) to setState. Am I on the right path?
exactly, you also can use closures instead of Promises, but anyway Promises is good point, also you can use the asymc await
1

You're giving an array of images to img and you're expecting it to handle it. Img tag can only accept one image at once:

<div> <input type="file" accept="image/jpeg, image/png" multiple onChange={this.onSelectFile} /> { photoList && photoList.map(photo => <img src={ photo } alt=""/>) } </div> 

2 Comments

thanks for replying. That makes sense, however, my main concern is that my state isn’t updating. I’ll update this post with a photo of state. Any thoughts?
Ok I'll wait for your update. But have you tried my solution?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.