javascript - 函数 setState 中的事件目标为 null

标签 javascript reactjs

考虑以下某些组件的功能:

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,
        }
    })
}

和一个输入,由上述组件的子组件呈现,并接收 handleInputChange 作为 props:

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

当我在输入中输入内容时出现错误,提示 Cannot read property 'value' of null

如果我取消注释 handleInputChange 函数中的第一行,其中我将输入值存储在 val 变量中,它运行良好。为什么?

最佳答案

那是因为 react before version 17正在做event pooling - 所有事件的字段在回调完成后都被取消,因此您在异步 setState 回调中将它们观察为空值。

请将您的事件数据复制到变量或调用 event.persist() 以禁用此行为。

handleInputChange(e) {
  e.persist();

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

或者:

handleInputChange(e) {
  const val = e.target.value;

  this.setState(function (prevState, props) {
      return {
        searchValue: val
      }
  })
}

请看下面的例子:

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>

关于javascript - 函数 setState 中的事件目标为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59522765/

相关文章:

javascript - typescript 不捆绑模块

javascript - AWS : Is createLogGroup operation idempotent?

javascript - SASS 中的动态类名

javascript - 为什么我的 jquery .get() 结果无法按我给出的顺序显示

javascript - Node js中的字符串正则表达式替换

javascript - 切换 div 显示在 ajax 请求后不起作用 - Javascript/Ajax

javascript - 我怎样才能只使用一次传播?

javascript - React : SlickGrid requires a valid container, #myGrid 在 DOM 中不存在

javascript - 钩子(Hook)中的延迟状态更改

javascript - 为什么 useState 会导致组件在每次更新时渲染两次?