TypeError:evt.target 在功能 setState 中为空

Posted

技术标签:

【中文标题】TypeError:evt.target 在功能 setState 中为空【英文标题】:TypeError: evt.target is null in functional setState 【发布时间】:2018-06-13 00:12:03 【问题描述】:

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

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

【问题讨论】:

***.com/a/42090588/4467208 有关 setState 的更多详细信息,请查看DOC,当下一个状态值依赖于先前的状态值时需要更新函数,而在您的情况下则不是。 【参考方案1】:

这是 setState 的两种不同语法

第一:

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

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

第二个:

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

使用要更新的对象

在更新函数中使用合成事件时需要使用event.persist()

来自documentation

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. 仅当您希望根据 prevStateprops 更新当前状态时,才应使用 setState 的更新程序功能

CodeSandbox

【讨论】:

那么在我的情况下,用回调更新状态是不是很没用?因为我读到更新状态的新标准方法是使用回调,不是吗?。 setState 中的更新程序函数的格式为 (prevState, props) =&gt; stateChange,因此如果您不需要访问前一个状态,我会说使用第二个只需要更新对象的状态。 React docs对调用setState的方法有很好的解释。 @margaretkru,是的,这是我们应该关心的最基本的事情。 @Shubham Khatri,您是否知道是否有任何详细的文档解释说明为什么在使用对象调用setState 时不需要调用event.persit() 或缓存来自事件的值,但是使用更新器功能时需要这样做吗? setState 在这两种情况下不应该异步工作吗?即使在controlled components 上对文档做出反应,也不要使用event.persist() @margaretkru,所以当您简单地编写 this.setState( tickerName: evt.target.value ); 时,您只是将一个对象传递给 setState,而 . tickerName 键的值是立即分配的,但是在更新程序函数中,它只不过是由 setState 使用必要参数调用的回调,到那时事件属性已无效。希望我能说清楚【参考方案2】:

React 将事件包装在自己的SyntheticEvent 中,其中will be reused and all properties will be nullified after the event callback has been invoked (请参阅react docs)。

根据react docs,无法以异步方式访问react SyntheticEvent,而setState 是异步的。因此,当setState 被执行时,你的evt 可能为空,因为它被react 重用。由于第一个函数使用回调来访问setState 中的先前状态,因此在执行回调时,事件evtreact 重用并取消。在第二种情况下,立即创建带有事件值的更新对象并直接传入,它不会产生类似的问题。

如果您需要将setState 与回调一起使用,您需要注意在执行回调时事件可能为空。处理此问题的一种方法是将对target 的原始引用存储在setState 之外,它将在setState 内部进行限定和使用。像这样:

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

我写了一个更详细的答案来解释为什么react 事件在setStatehere 中为空。

【讨论】:

以上是关于TypeError:evt.target 在功能 setState 中为空的主要内容,如果未能解决你的问题,请参考以下文章

强制文本输入为大写

删除表格当前行

forEach不是将多个图像上传到cloudinary的函数

阻止return键提交表单。

一键复制效果实现

checkbox选中selec才可选和显示隐藏密码