You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React异步函数中e.preventDefault()报错:不是函数的问题排查

React异步点击事件中e.preventDefault()报错的问题分析与解决

问题描述

我发现传入事件的函数中未调用preventDefault(),且defaultPrevented值为false,因此需要调用e.preventDefault()。但在异步函数中调用该方法时,出现报错:

Uncaught (in promise) TypeError: e.preventDefault is not a function

相关代码片段

const steps=(props,state,handleSave) = [
    {
    title:"Create Application"
    content:(
      <ApplicationForm
        initialValues={props.application}
        onSubmit={handleSave}
      />
    ),
    buttons:[
    <a
      onClick={async (e) => {
        const response = await handleSave(
          e,
          {
            ...props.formValues,
          }
        );
        if (response){
          return props.history.push({
            pathname: `${routes.EDIT_APPLICATION.dynamicRoute(
             props.application?.application_guid)}`,
          state: { current: 1 },
          });
        }
        return null;
       }}
    >
      Save Application
    </a>
    ]
    
export class ApplicationPage extends Component {
  state={
    current: 0, // 原代码此处用等号为语法错误,需改为冒号
  }
  
  handleSave = async(e, values) => {
    e.preventDefault(); // 此处报错:e.preventDefault is not a function
    const applicationFound = Boolean(values.application_guid);
    if (!applicationFound){
      return this.handleCreateApplication(values);
    }
    return this.handleUpdateApplication(values);
  };

事件对象属性详情

e: Class
altKey: false
bubbles: true
button: 0
buttons: 0
cancelable: true
clientX: 680
clientY: 241
ctrlKey: false
currentTarget: a
defaultPrevented: false
detail: 1
dispatchConfig: {phasedRegistrationNames: {…}, dependencies: Array(1), eventPriority: 0}
eventPhase: 3
getModifierState: ƒ modifierStateGetter(keyArg)
isDefaultPrevented: ƒ functionThatReturnsFalse()
length: 0
name: "functionThatReturnsFalse"
prototype: {constructor: ƒ}
arguments: (...)
caller: (...)
[[FunctionLocation]]: react-dom.development.js?7f13:8352
[[Prototype]]: ƒ ()
[[Scopes]]: Scopes[3]
isPropagationStopped: ƒ functionThatReturnsFalse()
isTrusted: true
metaKey: false
movementX: 0
movementY: 0
nativeEvent: PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
pageX: 680
pageY: 241
relatedTarget: null
screenX: -1368
screenY: 198
shiftKey: false
target: a
timeStamp: 1155255.8999999985
type: "click"
view: Window {window: Window, self: Window, document: document, name: '', location: Location, …}
_dispatchInstances: FiberNode {tag: 5, key: null, elementType: 'a', type: 'a', stateNode: a, …}
_dispatchListeners: ƒ (_x)
_targetInst: FiberNode {tag: 5, key: null, elementType: 'a', type: 'a', stateNode: a, …}
[[Prototype]]: Class

问题原因

核心原因是React的合成事件对象采用池化复用机制:当同步代码执行完毕后,React会自动回收合成事件对象,重置其所有属性和方法。在你的代码中,onClick是异步回调,await handleSave(...)会等待异步操作完成,此时React已经回收了原事件对象e,所以在handleSave中调用e.preventDefault()时,该方法已经不存在,从而触发报错。

从事件对象属性里的isDefaultPrevented: ƒ functionThatReturnsFalse()也能看出,事件对象已经被重置,原本的方法已失效。

解决方案

提供两种可行的解决办法:

1. 提前调用preventDefault()(推荐)

在onClick的同步代码阶段就调用e.preventDefault(),避免等到异步操作后事件对象被回收:

onClick={async (e) => {
  e.preventDefault(); // 提前调用,此时事件对象未被回收
  const response = await handleSave(
    { ...props.formValues }
  );
  if (response){
    return props.history.push({
      pathname: `${routes.EDIT_APPLICATION.dynamicRoute(
       props.application?.application_guid)}`,
    state: { current: 1 },
    });
  }
  return null;
}}

同时修改handleSave,移除不必要的事件参数:

handleSave = async(values) => {
  const applicationFound = Boolean(values.application_guid);
  if (!applicationFound){
    return this.handleCreateApplication(values);
  }
  return this.handleUpdateApplication(values);
};

2. 使用e.persist()保留事件对象

如果必须在异步逻辑中使用事件对象,可以调用e.persist()阻止React回收事件对象:

onClick={async (e) => {
  e.persist(); // 阻止事件对象被池化回收
  const response = await handleSave(
    e,
    { ...props.formValues }
  );
  // 后续逻辑...
}}

这种方式会让事件对象不进入池化,增加内存开销,不建议在高频触发的事件中使用。

另外注意:原代码中state的定义有语法错误,current=0应改为current: 0。


内容的提问来源于stack exchange,提问作者JarochoEngineer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:55:31