最近在做 React 项目时,使用 TS 语言结合开发,第一次尝试在 React 项目中用 TS 写,总结了一些常见的 Hook 类型定义的笔记,希望能帮助到大家,一起看一下吧。
useState
出场率极高的 Hook。
import { useState } from "react"; type userType = { name: string, age?: number } function App() { const [user, setUser] = useState<userType | null>(null) function handle() { setUser({ name: '张三', age: 18 }) console.log('33') } return ( <div className="App"> {user?.name} {user?.age} <button onClick={handle}>测试</button> </div> ); } export default App;
userType
是自定义的类型,意思是对象里面有两个参数name
、age
,age
可以为空(?是指可空)。
useState<userType | null>()
Hook 的返回值是userType
类型或null
,因为初始值null
,所以user
为null
,这样使用到user
就会有相应语法提示。
useRef
DOM
import { useRef } from "react"; function App() { const ref = useRef<HTMLDivElement>(null) function handle() { console.log(ref.current?.innerHTML) } return ( <> <div ref={ref} className="App" onClick={handle}>测试</div> </> ); } export default App;
HTMLDivElement
是 React 提供的类型,代表类型是一个 DOM 元素中的 DIV 元素,在使用ref.current
的时候有更好的代码提示 类似的 DOM 接口:
- HTMLInputElement(input) 代表 HTML 中的输入控件,如文本框、单选框、复选框等;
- HTMLButtonElement(button) 代表 HTML 中的按钮元素;
- HTMLImageElement(img) 代表 HTML 中的图像元素;
- HTMLAnchorElement(a) 代表 HTML 中的超链接元素;
- HTMLVideoElement(video) 代表 HTML 中的视频元素;
- HTMLAudioElement(audio) 代表 HTML 中的音频元素;
- HTMLIFrameElement(iframe) 代表 HTML 中的内联框架元素;
- HTMLOptionElement(option) 代表 HTML 中的选项元素;
- HTMLTableElement(table) 代表 HTML 中的表格元素;
- HTMLFormElement(form) 代表 HTML 中的表单元素。
定时器
import { useRef, useEffect } from "react"; function App() { const ref = useRef<number | null>(null) useEffect(() => { ref.current = window.setTimeout(() => { console.log('33') }, 1000) return clearTimeout(ref.current) }, []) return ( <> <div className="App">测试</div> </> ); } export default App;
ref.current
作为定时器的引用,可以保存定时器的标识符或引用。
useReducer
import { useReducer } from 'react'; type ActionType = { type: 'ADD' } const initialState = { count: 0 } function reducer(state: typeof initialState, action: ActionType) { const newState = {...state}; if(action.type === 'ADD') { newState.count = state.count + 1; } return newState; } function App() { const [ state, dispatch ] = useReducer(reducer, initialState) return ( <> <button onClick={() => {dispatch({ type: 'ADD' })}}>ADD</button> <div>{state.count}</div> </> ); } export default App;
reducer
函数中形参定义state
的类型使用到了typeof
,typeof
的作用是获取到initialState
的类型定义。
forwardRef 与 useImperativeHandle
这两个 Hook 组合一般用于在子组件定义事件,在父组件中调用,实现父子组件交互。
import { forwardRef, ReactNode, useImperativeHandle, useRef } from "react"; type propsType = { children: ReactNode } type refType = { start: () => void } const Child = forwardRef<any, propsType>((props, ref) => { useImperativeHandle(ref, () => { return { start(){ console.log('start') } } }) return ( <div>{props.children}</div> ) }) function App() { const ref = useRef<refType>(null!) return ( <> <button onClick={() => ref.current.start()}>按钮</button> <Child ref={ref}>测试</Child> </> ); } export default App;
子组件中接受两个参数props
和ref
类型分别是propsType
和any
(这里注意位置别搞混),暴露给父组件start
方法,在父组件中想有语法提示,必须在声明ref
的时候指定类型refType
。
useContext
import { createContext, useContext, useState } from "react"; type geenderType = { sex: '男' | '女' } const GenderValue = createContext<geenderType>({sex: '男'}) function Child() { const dender = useContext(GenderValue) return ( <div>{dender.sex}</div> ) } function App() { const [ sex, setSex ] = useState<geenderType>({sex: '男'}) return ( <GenderValue.Provider value={sex}> <button onClick={() => setSex({sex: '男'})}>按钮</button> <Child /> </GenderValue.Provider> ); } export default App;
创建 Context 对象的时候指定了类型为geenderType
,并赋初始值,注意在 App 组件中赋值的时候变量也应该遵守geenderType
定义的类型格式,这样在更改的时候只能是男或者女,避免出现其他值。
事件类型
- React.MouseEvent 鼠标点击事件;
- React.WheelEvent 鼠标滚轮事件;
- React.ToutchEvent 移动端触摸事件;
- React.ChanceEvent 输入框改变事件;
- React.FocusEvent 焦点事件;
- React.FormEvent 表单事件;
- React.KeyboardEvent 键盘事件。
import React from "react"; function App() { function handle(e: React.MouseEvent) { console.log(e.target) } return ( <div onClick={handle}>hello word</div> ); } export default App;
import React from "react"; function App() { function handle(e: React.ChangeEvent<HTMLInputElement>) { console.log(e.target.value) } return ( <input onChange={handle}>hello word</input> ); } export default App;
React.ChangeEvent<HTMLInputElement>
加上HTMLInputElement
类型输入e.target
会提示value
属性,配合 DOM 接口类型可以提供更智能的语法提示。
总结
大家在日常开发中,如果你 TS 类型写得好是可以提高代码质量,减少错误,增强代码的可维护性和可读性,从而提升整个项目的开发效率和稳定性。
以上就是常见 React Hook 的类型定义,个人笔记总结,如果有遗漏的欢迎大家评论留言指正,另外有个小技巧教给大家,如果想要检验 TS 类型定义是否标准,可以鼠标放在变量上看显示的类型是否跟数据的类型一致,而不是any
。