React TypeScript中如何通过Input的OnChange事件正确提交表单?
React+TypeScript 表单双重提交实现及类型错误解决
问题背景
需要实现表单既能通过提交按钮提交,也能通过输入框onChange事件提交,同时保留已有的onSomeOtherHandler处理逻辑。现有代码出现类型错误,因为ChangeEvent<HTMLInputElement>无法赋值给FormEvent<HTMLFormElement>。
现有代码
import React from 'react'; function App() { const onSomeOtherHandler = (event: React.ChangeEvent<HTMLInputElement>) => { // 自定义逻辑 }; const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 表单提交逻辑 }; return( <form onSubmit={handleFormSubmit}> <input onChange={(e) => { onSomeOtherHandler(e); handleFormSubmit(e); // 这里触发类型错误 } } /> <button type="submit"> Calculate </button> </form> ); } export default App;
类型错误信息
Argument of type 'ChangeEvent<HTMLInputElement>' is not assignable to parameter of type 'FormEvent<HTMLFormElement>'. Types of property 'currentTarget' are incompatible. Type 'EventTarget & HTMLInputElement' is not assignable to type 'EventTarget & HTMLFormElement'. Type 'EventTarget & HTMLInputElement' is missing the following properties from type 'HTMLFormElement': acceptCharset, action, elements, encoding, and 8 more.
解决方案
下面提供三种可行的实现方式,均能解决类型问题并满足需求:
方案1:通过表单Ref触发原生submit方法
利用useRef获取表单元素,直接调用其原生submit()方法,自动触发form的onSubmit事件,完全符合类型要求:
import React, { useRef } from 'react'; function App() { const formRef = useRef<HTMLFormElement>(null); const onSomeOtherHandler = (event: React.ChangeEvent<HTMLInputElement>) => { // 自定义逻辑 }; const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 表单提交逻辑 }; return( <form ref={formRef} onSubmit={handleFormSubmit}> <input onChange={(e) => { onSomeOtherHandler(e); formRef.current?.submit(); // 触发表单提交 } } /> <button type="submit"> Calculate </button> </form> ); } export default App;
方案2:重构提交逻辑,分离事件依赖
把表单提交的核心逻辑抽离成独立函数,让它不依赖FormEvent,这样不管是从onChange还是onSubmit都能调用:
import React from 'react'; function App() { const onSomeOtherHandler = (event: React.ChangeEvent<HTMLInputElement>) => { // 自定义逻辑 }; // 抽离核心提交逻辑 const handleSubmitLogic = () => { // 表单提交逻辑 }; const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); handleSubmitLogic(); }; return( <form onSubmit={handleFormSubmit}> <input onChange={(e) => { onSomeOtherHandler(e); handleSubmitLogic(); // 直接调用核心逻辑 } } /> <button type="submit"> Calculate </button> </form> ); } export default App;
方案3:触发提交按钮的点击事件
通过useRef获取提交按钮,调用其click()方法,间接触发表单提交:
import React, { useRef } from 'react'; function App() { const submitBtnRef = useRef<HTMLButtonElement>(null); const onSomeOtherHandler = (event: React.ChangeEvent<HTMLInputElement>) => { // 自定义逻辑 }; const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); // 表单提交逻辑 }; return( <form onSubmit={handleFormSubmit}> <input onChange={(e) => { onSomeOtherHandler(e); submitBtnRef.current?.click(); // 触发按钮点击 } } /> <button ref={submitBtnRef} type="submit"> Calculate </button> </form> ); } export default App;
内容的提问来源于stack exchange,提问作者Jorge Mauricio
相关产品推荐
相关产品推荐

