Reputation: 347
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..
Upvotes: 0
Views: 4333
Reputation: 18083
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)
}
Upvotes: 0
Reputation: 9118
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.
Upvotes: 2