0

I am trying to upload some files via <input type="file"> to the state, in order to pass it back to the main component. With the code below I get the Uncaught TypeError: Cannot read property 'setState' of undefined when trying to update the state with the uploaded files.

import React, { Component } from 'react' import * as RB from 'react-bootstrap' import Button from 'components/Button/Button' class uploadMob extends Component { constructor(props) { super(props) this.state = { files: [], } } onFilesAdded(files) { this.setState((prevState) => ({ files: prevState.files.concat(files), })) this.handleUpload() } handleUpload = (e) => { const { pdfUploadToState } = this.props debugger pdfUploadToState(this.state.files) console.log('PUSHED FILE', this.state.files) } render() { const files = this.state.files return ( <RB.Form.Group> <div className="upload-btn-wrapper"> <div className="Files"> {files.map((file, key) => { return ( <div key={key} className="Row"> <span className="Filename"> {file.value} </span> </div> ) })} </div> <Button size="sm" variant="light"> Dateien hochladen </Button> <input type="file" name="file" id="files" onChange={this.onFilesAdded} /> </div> </RB.Form.Group> ) } } export default uploadMob 

I would very much appreciate the help with this. It is driving me a bit crazy..

1
  • 1
    transform onFilesAdded to arrow function, it has problem now to find "this" of setState Commented Feb 6, 2020 at 15:30

2 Answers 2

2

The problem is with this line:

onFilesAdded(files) { 

You need to either bind() it to this like this:

constructor(props) { super(props) this.state = { files: [], }; this.onFilesAdded = this.onFilesAdded.bind(this); } 

or convert it to an arrow function:

onFilesAdded = files => { 

The problem is this referred inside onFilesAdded does not point the component instance by default. By using the two methods above, we make sure that by calling this., the component is correctly referred.

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

1 Comment

Thanks a lot!! That was it.
0

You need to use an arrow function to have the correct value of this.

setState is asynchronous so you need to pass the this.handleUpload function as a callback in order to updload the files once setState is completed.

From the documentation :

The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.

onFilesAdded = files => { this.setState(prevState => ({ files: [...prevState.files, ...files] }), this.handleUpdload) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.