Uploading multiple images with React

I would like to upload multiple images first by previewing them then submitting to send them off. I have encountered this: TypeError: Cannot read property 'files' of null. It also only lets me upload just one image.

  • I have created files: [] as means to mount the images for review before submitting.
  • Tried creating an interface files: File[] = file then declaring it in state but get a different error that file does not exist on type {}
import * as React from "react"

class ImageUpload extends React.Component {
  state: {
    files: []
  }

  fileSelectedHandler = (file: any) => {
    let addedFiles = this.state.files.concat(file)
    this.setState({ files: addedFiles })
    console.log("upload file " + file.name)
  }

  render() {
    return (
      < form >
        <div>
          <h2>Upload images</h2>
        </div>
        <h3>Images</h3>
        <input type="file" onChange={this.fileSelectedHandler} />
      </form>
    )
  }
}

export default ImageUpload

I expect it to allow me to select multiple images and store them in the array before sending them off as a batch. Is this even the right way to do it? Any feedback is greatly appreciated.

Answer

  1. In order to fix the error TypeError: Cannot read property 'files' of null. you need to change the state declaration
state = {
   files: []
}
  1. If you want to have the opportunity to select multiple files you can use multiple option
<input type="file" multiple onChange={this.fileSelectedHandler} />

Or if you want to select image one by one, your implementation should work, just fix the state declaration and use e.target.files to get selected file

class ImageUpload extends React.Component {
  state = {
    files: []
  }

  fileSelectedHandler = (e) => {
    this.setState({ files: [...this.state.files, ...e.target.files] })
  }

  render() {
    return (
      <form>
        <div><h2>Upload images</h2></div>
        <h3>Images</h3>
        <input type="file" multiple onChange={this.fileSelectedHandler} />
      </form>
    )
  }
}


ReactDOM.render(<ImageUpload />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>