Target is null inside function setState

Imagine the function of a component below:

handleInputChange(e) { // let val = e.target.value; - if I uncomment this, it works. // Update text box value this.setState(function (prevState, props) { return { searchValue: e.target.value, } }) } 

and a text field that is displayed by the child component of the above component and gets handleInputChange as props :

 <input type="text" onChange={that.props.handleInputChange} value={that.props.searchValue} /> 

When I type something in a text box, I get an error that Cannot read property 'value' of null .

If I uncomment the first line inside the handleInputChange function, where I store the value of the text field inside the val variable, this works well. Ideas why?

+17
source share
1 answer

This is because React runs the event pool - all event fields are reset to zero after the callback, so you observe them as zeros in the asynchronous setState .

Please copy your event data into a variable or call event.persist() to disable this behavior.

 handleInputChange(e) { e.persist(); this.setState(function (prevState, props) { return { searchValue: e.target.value, } }) } 

Or:

 handleInputChange(e) { const val = e.target.value; this.setState(function (prevState, props) { return { searchValue: val } }) } 

Please see the following example:

 class Example extends React.Component { constructor() { super() this.state = { } } handleInputChangeCopy = (e) => { const val = e.target.value; console.log('in callback'); console.log(e.target.value); this.setState(function (prevState, props) { console.log('in async callback'); console.log(val); return { searchValue: val } }) } handleInputChangePersist = (e) => { e.persist(); console.log('in callback'); console.log(e.target.value); this.setState(function (prevState, props) { console.log('in async callback'); console.log({ isNull: e.target === null }) console.log(e.target.value); return { searchValue: e.target.value } }) } handleInputChange = (e) => { console.log('in callback'); console.log(e.target.value); this.setState(function (prevState, props) { console.log('in async callback'); console.log({ isNull: e.target === null }) console.log({ event: e }); console.log(e.target.value); return { searchValue: e.target.value } }) } render() { return ( <div> <div>Copy example</div> <input type="text" onChange={this.handleInputChangeCopy} /> <p>Persist example</p> <input type="text" onChange={this.handleInputChangePersist} /> <p>Original example - please note nullified fields of the event in the async callback. <small>Breaks the example, please re-run after a Script error</small></p> <input type="text" onChange={this.handleInputChange} /> <div style={{height: 300}} /> </div> ) } } ReactDOM.render( <Example searchValue={"test"} />, document.getElementById('app') ) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div> 
+26
source

Source: https://habr.com/ru/post/1269134/


All Articles