React表单调用原生submit()未触发onSubmit事件的适配方案咨询
解决方案
核心思路是重写表单DOM元素的原生submit方法,在第三方脚本调用该方法时主动触发我们需要的登录逻辑,不需要修改任何第三方脚本代码。
具体实现步骤如下:
- 给表单元素绑定
useRef获取真实DOM引用 - 组件挂载后重写表单的
submit方法,主动派发submit事件,让React绑定的onSubmit处理函数可以正常执行
修改后的完整组件代码如下:
import { useState, useRef, useEffect } from 'react'; function Login() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [loggedIn, setLoggedIn] = useState(false); // 新增:获取表单DOM的ref const formRef = useRef(null); function handleSubmit(event){ event?.preventDefault(); // 原来的登录逻辑保持不变 } // 新增:重写表单submit方法 useEffect(() => { const form = formRef.current; if (!form) return; // 保存原生submit方法,如果你需要保留原生表单提交行为可以后续调用 const originalSubmit = form.submit.bind(form); form.submit = () => { // 手动派发submit事件,触发React绑定的onSubmit逻辑 form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true })); // 如果你的登录逻辑不需要原生表单跳转,下面这行可以删掉 // originalSubmit(); }; }, []); if(loggedIn) return <Afterlogin />; return ( <div className="login"> {/* 给form加ref */} <form ref={formRef} id="login" className="login__container" onSubmit={handleSubmit} > <input id="username" type="text" name="username" className="login__textBox" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="name" /> <input id="password" type="password" name="password" className="login__textBox" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="password" /> <button className="login__btn" type='submit' > login </button> </form> </div> ); }
注意事项
如果你的handleSubmit函数依赖组件内的响应式状态,建议用useCallback包裹handleSubmit,并将其添加到useEffect的依赖数组中,避免执行逻辑过时。
内容的提问来源于stack exchange,提问作者zlZimon
相关产品推荐
相关产品推荐

