Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

input's event.target is null within this.setState [React.js]

In my react component I have a file input:

<input type="file" onChange={this.onFileChange.bind(this)} />` 

and my onFileChange is:

onFileChange(e) {
  let file = e.target.files[0];
  this.setState(() => ({ file: e.target.files[0] })); //doesnt work
  // this.setState(() => ({ file })); //works
  // this.setState({ file: e.target.files[0] }); //works
}

This first way of setting the states fails with an error:

Cannot read property 'files' of null

React also gives the following warning:

This synthetic event is reused for performance reasons. If you're 
seeing this, you're accessing the property 'target' on a 
released/nullified synthetic event

But the last two ways of setting the state give no errors or warnings. Why is this happening?

like image 744
S_Farsai Avatar asked Nov 22 '17 19:11

S_Farsai


3 Answers

The setState function is executed in asynchronous context.

By the time the state is updated the e.target reference might or might not be gone.

const file = e.target.files[0]; can be used to "remember" the value as in your example.

like image 182
Kunukn Avatar answered Nov 08 '22 17:11

Kunukn


What is the reason for calling setState with callback ? this.setState({ file: e.target.files[0] }) should do the job.

In your code you are referring to a synthetic event object which no longer holds information about the original DOM event. React reuses the event objects for performance reasons.

Alternatively you can use:

let file = e.target.files[0]; const files = e.target.files this.setState(() => ({ file: files[0] })); //doesnt work

like image 41
ps-aux Avatar answered Nov 08 '22 15:11

ps-aux


React uses event pooling, you can read more about it in the docs here https://reactjs.org/docs/events.html

setState is an asynchronous function

this.setState(() => ({ file })); // is correct
like image 24
Eric Hasselbring Avatar answered Nov 08 '22 15:11

Eric Hasselbring