类型错误:函数setState中evt.target为空。

问题描述 投票:0回答:1

这两个函数的主要区别是什么?

handleOnChange(evt) {
    this.setState(() => ({
        tickerName: evt.target.value
    }));
}

handleOnChange(evt) {
    this.setState({ tickerName: evt.target.value });
}

为什么用handleOnChange()函数直接改变状态就能正常工作?

<input
    type="text"
    value={this.state.tickerName}
    onChange={(evt) => this.handleOnChange(evt)} 
/>

当我使用第一个用回调改变状态的函数时,我得到了这个错误。

TypeError: evt.target is null
javascript reactjs events filereader use-state
1个回答
7
投票

这是setState的两个不同的语法。

第一:使用更新器函数作为第一个参数。

handleOnChange(evt) {
    this.setState(() => ({
        tickerName: evt.target.value
    }));
}

使用更新器函数作为第一个参数。

第二:使用要更新的对象作为第一个参数。

handleOnChange(evt) {
   this.setState({ tickerName: evt.target.value });
}

使用要更新的对象

当在更新器功能中使用合成事件时,你需要使用 event.persist()

来自 文件:

SyntheticEvent是池化的。这意味着SyntheticEvent对象将被重复使用,并且在事件回调被调用后,所有属性将被清零。这是出于性能方面的考虑。因此,您不能以异步方式访问事件。

如果你想以异步方式访问事件属性,你应该在事件上调用event.persist(),这将从池中移除合成事件,并允许用户代码保留对事件的引用。

你的第一个案例会是这样的

handleOnChange(evt) {
    evt.persist();
    this.setState(() => ({
        tickerName: evt.target.value
    }));
}

或者不使用 event.persist() 你可以将事件存储在另一个对象中

handleOnChange(evt) {
    const value = evt.target.value;
    this.setState(() => ({
        tickerName: evt.target.value
    }));
}

P.S. 只有当你想根据当前状态更新的时候,才可以使用setState的updater函数。prevStateprops

CodeSandbox


2
投票

React 将事件包装在自己的 SyntheticEvent 其中 will be reused and all properties will be nullified after the event callback has been invoked (见 反应文档).

根据 反应文档,不能访问反应 SyntheticEvent 以异步方式和 setState 是异步的。所以当 setState 你的 evt 可能是空的,因为它被 react. 由于第一个函数使用的是回调,可以访问之前在 setState,当回调执行时,事件 evt 被重复使用,并由 react. 在第二种情况下,带有事件值的update对象会被立即创建并直接传入,不会产生类似的问题。

如果你需要使用 setState 的回调,你需要注意当回调被执行时事件可能是空的。处理这种情况的一种方法是将原始引用存储到 target 在...之外 setState 它将被范围化,并在内部使用 setState. 像这样。

handleOnChange(evt) {
    const target = evt.target;
    this.setState((prevState) => ({
        tickerName: target.value
    }));
}

我写了一个更详细的答案,为什么 react 事件在 setState 此处.

© www.soinside.com 2019 - 2024. All rights reserved.