I'm trying to read a file that the user uploads in a React ponent and set the state of the React ponent to the file contents. However, in the read.onloadend
callback function, I can't access the state through this
.
Here is the actual form part (I am using react-bootstrap)
<FormGroup>
<FormControl
id="fileUpload"
type="file"
accept=".txt"
onChange={this.handleSubmit.bind(this)}
/>
</FormGroup>
And here is my function to handle submit:
handleSubmit(e) {
e.preventDefault()
let inputtext;
let file = e.target.files[0];
let read = new FileReader();
read.readAsBinaryString(file);
read.onloadend = function(){
this.setState({filetext : read.result});
}
read.onloadend.bind(this);
}
I'm trying to read a file that the user uploads in a React ponent and set the state of the React ponent to the file contents. However, in the read.onloadend
callback function, I can't access the state through this
.
Here is the actual form part (I am using react-bootstrap)
<FormGroup>
<FormControl
id="fileUpload"
type="file"
accept=".txt"
onChange={this.handleSubmit.bind(this)}
/>
</FormGroup>
And here is my function to handle submit:
handleSubmit(e) {
e.preventDefault()
let inputtext;
let file = e.target.files[0];
let read = new FileReader();
read.readAsBinaryString(file);
read.onloadend = function(){
this.setState({filetext : read.result});
}
read.onloadend.bind(this);
}
Share
Improve this question
asked Mar 5, 2018 at 4:04
Josiah CoadJosiah Coad
3554 silver badges11 bronze badges
2
- please check working example to here codepen.io/santoshshinde2012/pen/XZwgLJ – Santosh Shinde Commented Mar 5, 2018 at 4:26
- If following answers solves your problem, please mark anyone as accepted and upvote. So that people can go ahead and solve other's questions. – zamil Commented Mar 5, 2018 at 4:46
3 Answers
Reset to default 7Just use an arrow function.
That way this
will not change.
handleSubmit(e) {
e.preventDefault()
let inputtext;
let file = e.target.files[0];
let read = new FileReader();
read.readAsBinaryString(file);
read.onloadend = () => {
this.setState({filetext : read.result});
}
}
https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this
It fails in the onload callback due to changed context (this
). JavaScript natively change the context in callback. In your case in onload this is the same as reader.
Solution1: Use arrow operator (() =>
).
Solution2: Assign that
variable in parent scope of this
.
Use following code
read.onloadend = () => {
this.setState({filetext : read.result});
}
OR
handleSubmit(e) {
e.preventDefault()
// assign parent scope to here
let that = this;
let inputtext;
let file = e.target.files[0];
let read = new FileReader();
read.readAsBinaryString(file);
read.onloadend = function(){
that.setState({filetext : read.result});
}
read.onloadend.bind(this);
}
Please check the working example to here.
Hope this will help you!!
Since you don't have access to this inside. You have to implement it in following way.
handleSubmit(e) {
e.preventDefault()
let _this = this;
let inputtext;
let file = e.target.files[0];
let read = new FileReader();
read.readAsBinaryString(file);
read.onloadend = function(){
_this.setState({filetext : read.result});
console.log(read.result);
}
read.onloadend.bind(this);
}
<FormGroup>
<FormControl
id="fileUpload"
type="file"
accept=".txt"
onChange={this.handleSubmit.bind(this)}
/>
</FormGroup>