当前位置: 首页 > news >正文

useActionState 阻止表单重置

前言

useActionState是react19新出的api,提供的非受控表单钩子。
但是他有一个缺点,就是每次提交表单后会重置表单状态!

官方美其名曰“遵守原生表现”,但是网上讨伐声音,就足以证明垃圾!
https://github.com/facebook/react/issues/29034
https://github.com/facebook/react/issues/30580

方式1(推荐)

定义重写全局的 form reset,新建 preventGlobalFormReset.ts

/*** 全局 Patch HTMLFormElement.prototype.reset 方法* 阻止 React 19 useActionState 自动重置表单* 参考: https://github.com/facebook/react/issues/29034** 使用方法:在应用入口调用一次 patchFormReset()** 控制选项:* - 默认:阻止所有表单重置* - <form data-allow-reset>:允许该表单重置* - <form data-prevent-reset>:明确阻止该表单重置* - formRef.current.reset(true):手动调用时传入 true 强制重置*/// 保存原始方法的引用
let originalReset: typeof HTMLFormElement.prototype.reset | null = null;export function patchFormReset(options?: {/** 默认行为:'prevent' 阻止重置 | 'allow' 允许重置 */defaultBehavior?: 'prevent' | 'allow';
}) {if (typeof window === 'undefined') return;if (originalReset) {console.warn('[patchFormReset] 已经 patch 过了,跳过');return;}const { defaultBehavior = 'prevent' } = options || {};// 保存原始的 reset 方法originalReset = HTMLFormElement.prototype.reset;// 重写 reset 方法,支持传入参数强制重置HTMLFormElement.prototype.reset = function (this: HTMLFormElement, force?: boolean) {// 如果传入 true,强制重置if (force === true) {originalReset!.call(this);return;}// 检查表单上的属性const hasAllowReset = this.hasAttribute('data-allow-reset');const hasPreventReset = this.hasAttribute('data-prevent-reset');let shouldReset = defaultBehavior === 'allow';// 属性优先级高于默认行为if (hasAllowReset) {shouldReset = true;} else if (hasPreventReset) {shouldReset = false;}if (shouldReset) {originalReset!.call(this);} else {// 什么都不做,阻止重置}};
}/*** 恢复原始的 reset 方法*/
export function unpatchFormReset() {if (typeof window === 'undefined') return;if (!originalReset) {console.warn('[unpatchFormReset] 没有找到原始的 reset 方法');return;}HTMLFormElement.prototype.reset = originalReset;originalReset = null;console.log('[unpatchFormReset] HTMLFormElement.prototype.reset 已恢复');
}

在 main.ts 调用即可

// 全局阻止 React 19 useActionState 自动重置表单
patchFormReset({defaultBehavior: 'prevent', // 默认阻止重置
});

在组件中,如果想要手动调用重置,仍然可以,只不过加一个强制即可!

formRef.current.reset(true);

方式 2

如果你不想污染全局,可以这么做
订一个一个 hook,usePreventFormReset.ts

import { useEffect, useRef } from 'react';/*** 阻止 React 19 useActionState 自动重置表单* 参考: https://github.com/facebook/react/issues/29034#issuecomment-2843233452*/
export function usePreventFormReset() {const formRef = useRef<HTMLFormElement>(null);useEffect(() => {const watchReset = (e: Event) => e.preventDefault();formRef.current?.addEventListener('reset', watchReset);return () => formRef.current?.removeEventListener('reset', watchReset);}, []);return formRef;
}

然后组件内使用即可

// 阻止表单重置
const formRef = usePreventFormReset();<form action={formAction} ref={formRef}>
// ***
</form>
http://www.jsqmd.com/news/38790/

相关文章:

  • 路由基础
  • idea链接database时报错:serverTimezone
  • 题解:CF2117F Wildflower
  • UVM环境自动生成器具(2)uvmdvgen
  • 题解:CF961C Chessboard
  • 7年java开发的一些感悟
  • 11.12 NOIP模拟6/多校1 改题记录
  • 文字识别系统代码
  • B4093 [CSP-X2021 山东] 发送快递
  • 从零上手 Rokid JSAR:打造专属 AR 桌面交互式 3D魔方,开启空间创建之旅
  • 微软2025年11月补丁星期二修复1个零日漏洞和63个安全漏洞
  • CF468C Hack it!
  • 深入解析:FT62FC3X 8位MCU单片机选型表,详细解析FT62FC31A/32A/33A/35A/3FA
  • 语法记录
  • Can Large Language Models Detect Rumors on Social Media?
  • 压迫
  • P13573 [CCPC 2024 重庆站] Pico Park
  • 手工安装gcc-13.3.0
  • 深入解析:Cookie、Session、JWT、SSO,网站与 APP 登录持久化与缓存
  • gowin ide linux安装教程
  • AT_arc111_f [ARC111F] Do you like query problems?
  • Win7 隐藏文件夹盘符
  • pythontip 按条件过滤字典
  • DotNetGuide 突破了 9.5K + Star,一份全面的C#/.NET/.NET Core学习、工作、面试指南知识库!
  • 如何把华为mate 60手机备份到移动硬盘
  • Vue实例学习
  • 2.2 语言处理程序基础
  • Ai元人文:价值的“迷思”与“归真”——从家庭之爱到文明共生
  • MATLAB 数据可视化教程:从基础到进阶
  • 在ec2上部署qwen3-VL-2B模型