Event target is null inside functional setState

后端 未结 1 1113
伪装坚强ぢ
伪装坚强ぢ 2020-12-02 17:38

Imagine below function of some component:

handleInputChange(e) {
    // let val = e.target.value; - if I uncomment this, it works.

    // Update text box va         


        
相关标签:
1条回答
  • 2020-12-02 17:46

    That is because of React doing event pooling - all the event's fields get nullified after the callback is done, so you observe them as nulls in the asynchronous setState callback.

    Please copy your event data to 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>

    0 讨论(0)
提交回复
热议问题