React TypeScript Cheatsheet:表单与事件——为 React 事件处理函数赋予完整类型安全
React TypeScript Cheatsheet表单与事件——为 React 事件处理函数赋予完整类型安全【免费下载链接】reactCheatsheets for experienced React developers getting started with TypeScript项目地址: https://gitcode.com/gh_mirrors/reactt/react-typescript-cheatsheet本文基于 React TypeScript Cheatsheet 仓库中的 Forms and Events 章节展开系统讲解在 React TypeScript 项目中如何为表单输入onChange和表单提交onSubmit等事件处理函数编写类型从最省事的内联手写 上下文类型推断到显式标注React.ChangeEvent/React.ChangeEventHandler再到使用React.SyntheticEvent与类型断言读取自定义命名的非受控表单控件。读完后你将掌握仓库推荐的各类事件类型写法、React 19 中的事件类型弃用注意事项以及一张可直接用于查证的 React 事件类型速查表。适用前提与本仓库的定位本 Cheatsheet 面向有经验的 React 开发者入门 TypeScript。按照 Introductionsetup 的说明其前提与约束是具备 React 的基础理解以及 TypeScript 基础类型与日常类型Everyday Types的熟悉度Cheatsheet 假设你使用最新版本的 React 和 TypeScript——这一点在本章的事件类型弃用小节中尤为关键该文档在网站导航中属于 Learn 分类位于 website/sidebars.json 中的basic/getting-started/forms_and_events其 front-matter 标题为 Forms and Events。首选方案内联事件处理函数 上下文类型推断仓库给出的第一原则是如果性能不是问题而且通常都不是问题直接内联事件处理函数是最简单的做法。因为 TypeScript 的**类型推断与上下文类型contextual typing**会替你把事件参数自动推断出正确类型——你甚至不需要写任何显式类型标注const el ( button onClick{(event) { /* event will be correctly typed automatically! */ }} / );这里event会被自动推断为与button的onClick相匹配的鼠标事件类型即React.MouseEventHTMLButtonElement无需任何额外标注。这是函数组件中编写事件处理器的默认推荐姿势。独立定义事件处理函数在等号右侧标注参数类型当性能敏感需要稳定的函数引用以避免子组件不必要重渲染、或逻辑足够复杂需要单独命名时你会把事件处理函数定义在 JSX 之外。此时types/react提供了非常丰富的类型可供自动补全——输入你在找的类型名IDE 的自动补全通常就能帮到你。仓库给出的onChange示例类组件场景如下type State { text: string; }; class App extends React.ComponentProps, State { state { text: , }; // typing on RIGHT hand side of onChange (e: React.FormEventHTMLInputElement): void { this.setState({ text: e.currentTarget.value }); }; render() { return ( div input typetext value{this.state.text} onChange{this.onChange} / /div ); } }要点解析标注位置在等号右侧即在箭头函数的参数与返回值上显式写出(e: React.FormEventHTMLInputElement): voidReact.FormEventT的泛型参数T是触发事件的元素类型这里是HTMLInputElement因此e.currentTarget被精确推断为HTMLInputElement可以安全访问.valuethis.setState({ text: e.currentTarget.value })展示了事件值如何流入受控组件的 state与 Class Components 章节中React.ComponentPropType, StateType的泛型用法一脉相承示例中的Props可理解为组件已定义的 props 类型与 class components 章节的MyProps角色一致注意使用e.currentTarget而非e.target在 React 的池化/异步事件模型下currentTarget是更可靠的选择且其类型就是泛型参数T。另一种写法在等号左侧整体标注处理函数类型不标注参数与返回值而是直接给处理函数本身赋予types/react中官方钦定blessed的委托类型同样可以完成类型化该写法由社区贡献者 TomasHubelbauer 贡献// typing on LEFT hand side of onChange: React.ChangeEventHandlerHTMLInputElement (e) { this.setState({ text: e.currentTarget.value }); };为什么存在两种等价写法原文档专门用折叠小节解释了这个问题这里完整继承第一种写法右侧标注使用的是手工推断/手写的函数签名(e: React.FormEventHTMLInputElement): void第二种写法左侧标注直接采用types/react提供的现成委托类型React.ChangeEventHandlerT。可以把它理解为types/react官方封装好的类型别名本质是(event: ChangeEventT) void的包装而第一种更像手工作坊式artisanally hand-rolled的签名原文档明确说两种方式都是值得掌握的好模式。在 Cheatsheet 的另外一篇文档 Basic Type Examples 中你也可以看到这两种风格的交叉出现——props 类型里既写了onChange: (event: React.ChangeEventHTMLInputElement) void手写签名风格也写了onChange?: React.FormEventHandlerHTMLInputElementblessed 别名风格并特别注明泛型参数是event.target的类型。React 19 的事件类型弃用说明重要仓库文档中有一条明确的版本提示见 forms-and-events.md 的注记Starting with React v19.2.10FormEventandFormEventHandlerare deprecated and should be replaced withSubmitEventandSubmitEventHandler. The older event types will still work but trigger a deprecation message.翻译并给出实操含义从React v19.2.10起FormEvent与FormEventHandler被标记为弃用deprecated旧的事件类型仍然可用但会触发弃用提示文档建议以SubmitEvent/SubmitEventHandler替代它们。由于本 Cheatsheet 整体假设使用最新版本的 React见 setup在 React 19 项目中编写新代码时涉及表单提交语义的事件类型应优先采用新的命名需要留意的是ChangeEvent/ChangeEventHandler并不在此弃用范围内输入框onChange的写法不受影响受影响的只是上文示例中React.FormEvent这一处标注。非受控表单中的 onSubmit 类型SyntheticEvent 类型断言对于非受控组件uncontrolled components即不通过value/onChange受控、只关心提交时的取值的form onSubmit仓库给出了如下完整方案如果你不关心事件的具体类型可以直接使用基类React.SyntheticEvent若表单里有你按name命名的自定义输入项想要读取就用类型断言给e.target补充形状form ref{formRef} onSubmit{(e: React.SyntheticEvent) { e.preventDefault(); const target e.target as typeof e.target { email: { value: string }; password: { value: string }; }; const email target.email.value; // typechecks! const password target.password.value; // typechecks! // etc... }} div label Email: input typeemail nameemail / /label /div div label Password: input typepassword namepassword / /label /div div input typesubmit valueLog in / /div /form关键机制说明e.preventDefault()阻止默认提交行为这在类型上完全无需额外标注断言的核心表达式是e.target as typeof e.target { ... }用**交叉类型intersection type**在原有 target 类型的基础上叠加出email/password两个按 name 访问的属性每个属性都是{ value: string }形状——这样既保留了原 target 的类型信息又让target.email.value、target.password.value都能通过类型检查这种断言只对确实存在同名 name 属性的控件成立name与断言字段的对应关系由你自己保证类型系统帮你守住的是访问路径的形状。更复杂的表单交给专用表单库原文档的收尾建议是如果你在做任何有一定规模的表单应直接使用 Formik 或 React Hook Form 这类表单库——它们本身就是用 TypeScript 编写的能提供更完整的类型化表单模型而不需要手写这类断言。React 事件类型速查表原文档附有完整的事件类型清单List of event types这是本章节最具查阅价值的部分完整继承如下Event TypeDescriptionAnimationEventCSS Animations.CSS 动画事件ChangeEventChanging the value ofinput,selectandtextareaelement.input、select、textarea元素值改变时触发ClipboardEventUsing copy, paste and cut events.复制、粘贴、剪切事件CompositionEventEvents that occur due to the user indirectly entering text.用户间接输入文字时触发的事件例如在美式键盘上输入日文时可能出现附加字符选择窗口DragEventDrag and drop interaction with a pointer device (e.g. mouse).通过指针设备如鼠标进行的拖放交互FocusEventEvent that occurs when elements gets or loses focus.元素获得或失去焦点时触发FormEventEvent that occurs whenever a form or form element gets/loses focus, a form element value is changed or the form is submitted.表单或表单元素获得/失去焦点、表单元素值改变或表单提交时触发注意 React 19.2.10 起已弃用见前文说明InvalidEventFired when validity restrictions of an input fails.当输入的有效性约束校验失败时触发例如input typenumber max10中填入了 20KeyboardEventUser interaction with the keyboard. Each event describes a single key interaction.用户与键盘的交互每个事件描述一次按键交互InputEventEvent that occurs before the value ofinput,selectandtextareachanges.在input、select、textarea的值改变之前触发MouseEventEvents that occur due to the user interacting with a pointing device (e.g. mouse)用户与指针设备如鼠标交互产生的事件PointerEventEvents that occur due to user interaction with a variety pointing of devices such as mouse, pen/stylus, a touchscreen and which also supports multi-touch. Unless you develop for older browsers (IE10 or Safari 12), pointer events are recommended. Extends UIEvent.用户与鼠标、笔/触控笔、触摸屏等多种指向设备交互且支持多点触控产生的事件除非需要兼容 IE10 或 Safari 12 等旧浏览器否则推荐优先使用 Pointer Events。继承自 UIEventTouchEventEvents that occur due to the user interacting with a touch device. Extends UIEvent.用户与触摸设备交互产生的事件。继承自 UIEventTransitionEventCSS Transition. Not fully browser supported. Extends UIEvent.CSS 过渡事件浏览器支持不完全。继承自 UIEventUIEventBase Event for Mouse, Touch and Pointer events.鼠标、触摸、指针事件的基类事件WheelEventScrolling on a mouse wheel or similar input device. (Note:wheelevent should not be confused with thescrollevent)滚轮或类似输入设备的滚动事件注意wheel事件不应与scroll事件混淆SyntheticEventThe base event for all above events. Should be used when unsure about event type.以上所有事件的基类不确定具体事件类型时应使用它选型建议可直接从表中读出拿不准类型时退回SyntheticEvent表单提交优先SubmitEventReact 19.2.10 起替代弃用的FormEvent输入控件用ChangeEvent交互类设备事件优先PointerEvent。与仓库其他章节的关联本篇的写法并非孤立存在结合仓库结构可以看到它的上下游关系props 中的事件类型Basic Prop Types Examples 章节给出了把事件处理函数作为 prop 传递时的类型写法例如onChange: (event: React.ChangeEventHTMLInputElement) void与onChange?: React.FormEventHandlerHTMLInputElement注释强调泛型参数是event.target的类型与本篇独立定义处理函数的两种风格互相印证包装组件透传事件 propsUseful Patterns by Use Case 中的 Wrapping/Mirroring 模式React.ComponentPropsWithoutRefbuttonrest展开会让onClick/onSubmit等事件属性随rest原样透传给内层元素——事件类型系统在这里保证了透传后类型依然精确类组件基础本篇的onChange示例建立在 Class Components 的React.ComponentProps, State泛型用法之上state 的双重标注等细节可回到该章节查阅。小结与可落地清单性能不敏感时内联箭头函数依赖上下文推断零标注onClick{(event) {...}}需要独立命名/引用时二选一——右侧手写(e: React.FormEventHTMLInputElement): void或左侧整体标注React.ChangeEventHandlerHTMLInputElement表单提交且不想关心事件具体类型React.SyntheticEventtypeof e.target { ... }断言读取按 name 命名的控件值复杂表单改用 Formik / React Hook Form 等 TypeScript 编写的表单库版本敏感点React v19.2.10 起FormEvent/FormEventHandler弃用新代码提交语义事件改用SubmitEvent/SubmitEventHandlerChangeEvent系列不受影响查阅事件类型以上文速查表为准拿不准就用SyntheticEvent。相关仓库文件Forms and Events 原文Introduction / SetupBasic Type ExamplesClass ComponentsUseful Patterns by Use Case网站导航配置【免费下载链接】reactCheatsheets for experienced React developers getting started with TypeScript项目地址: https://gitcode.com/gh_mirrors/reactt/react-typescript-cheatsheet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →