React中避免类型断言,将表单转为FormData的优化实现
问题:React中避免类型断言创建FormData的最优实现方式
我尝试将表单中的值存入FormData,当前实现代码如下:
const handleSubmit = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); const value = formData.get('origin') ? 'open' : 'on'; updateResizingOptionsQuery.mutate({ value }); };
由于React传递的是SyntheticEvent,e.target的接口不符合FormData构造函数的要求,目前我使用了类型断言,但这并非理想方案。若不添加类型断言,会触发如下lint错误:
Argument of type 'EventTarget' is not assignable to parameter of type 'HTMLFormElement'.
Type 'EventTarget' is missing the following properties from type 'HTMLFormElement': acceptCharset, action, autocomplete, elements, and 297 more.
请问该代码的更优实现方式是什么?
最优实现方案
方法1:使用e.currentTarget替代e.target
在React的FormEvent中,currentTarget的类型会自动绑定为事件所附着的元素类型(这里就是HTMLFormElement),完全符合FormData构造函数的参数要求,无需类型断言:
const handleSubmit = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const value = formData.get('origin') ? 'open' : 'on'; updateResizingOptionsQuery.mutate({ value }); };
方法2:通过useRef获取表单元素
如果需要更直接地控制表单元素,可以使用React的useRef钩子获取表单实例,同样能保证类型安全:
import { useRef, FormEvent } from 'react'; // 组件内部创建ref const formRef = useRef<HTMLFormElement>(null); const handleSubmit = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); if (!formRef.current) return; const formData = new FormData(formRef.current); const value = formData.get('origin') ? 'open' : 'on'; updateResizingOptionsQuery.mutate({ value }); }; // 表单元素绑定ref return <form ref={formRef} onSubmit={handleSubmit}>...</form>;
这两种方案都能避免类型断言带来的潜在类型风险,同时保持代码的类型安全性和可读性。
内容的提问来源于stack exchange,提问作者Xen_mar
相关产品推荐
相关产品推荐

