为什么较新的“ setState”方法无法识别我的event.target?

时间:2018-08-17 23:19:06

标签: reactjs

是否不建议将新的setState语法用于事件? 调试时,我看到键入的第一个字母是 正确的e.target.value。 不过,随后我立即收到了您在下面看到的TypeError。

// onChange(e) {
//     this.setState(prevState => {
//        return { username: e.target.value} <--- TypeError: Cannot read property 'value' of null
//     })
// }

//显然下面的setState可以正常工作

onChange(e) {
    this.setState({ username: e.target.value});
}

<input  type="text"
        placeholder="What is your username?"
        onChange={this.onChange}
        // onChange={e => this.onChange(e)} - also tried this
        value={this.state.username}/>

2 个答案:

答案 0 :(得分:3)

通过在传递给setState()的回调函数中访问事件,可以异步方式使用该事件。在React调用您的updater函数时,事件的所有属性都已清除。

From the react docs

  

SyntheticEvent已合并。这意味着SyntheticEvent   对象将被重用,并且所有属性将在   事件回调已被调用。这是出于性能原因。如   这样,您将无法以异步方式访问事件。

为避免这种情况,您需要通过调用event.perist()来保留事件。这将使您以后可以使用它。

或者您将感兴趣的value分配给可以异步使用的局部变量:

onChange(e) {
    const username = e.target.value;
    this.setState(prevState => ({username}));
}

实际上,在您的特定示例中,您根本不需要基于setState()的基于回调的版本,因为您不是基于先前的状态或道具来更新状态。

答案 1 :(得分:0)

更新

我首先错过的错误是e.target在这里为空。因此,真正的问题不是从事件中提取值,也不是在@trixn在他/她的答案中说明的地方使用event.persist()。但是,我的答案虽然包括这一步。因此,它起作用了:)


如果您没有为onChange绑定this函数,则它们都不起作用。这是您说不起作用的代码的有效版本:

class App extends React.Component {
  state = { username: "" };
   onChange = (e) => {
     const { value } = e.target;
     this.setState(prevState => {
       return { username: value}
   })
 }

  render() {
    return (
      <div>
        <input type="text"
          placeholder="What is your username?"
          onChange={this.onChange}
          value={this.state.username} />
        <p>Username: {this.state.username}</p>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>

我只是使用了箭头功能,而不是隐式绑定它。因此它是自动绑定的。另外,我从value中提取了e.target用于React的综合事件处理。如果像在setState这样的回调函数中使用事件,我们将无法正确使用事件。这就是为什么我提取它然后将其用作单独变量的原因。