React 遇到 TS 必须掌握的Hook类型定义

最近一段时间在做 React 项目,用的是TS语言,第一次尝试用TS写项目,刚开始用静态类型写前端还不太适应,处处碰壁。我自己总结了一些常见的Hook类型定义,希望能帮助到大家

useState

出场率极高的Hook,之前也在文章中给大家介绍过 Vue转React 3分钟学会useState 大家有兴趣可以看看

ts 复制代码
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,所以usernull,这样使用到user就会有相应语法提示

useRef

DOM

ts 复制代码
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中的表单元素

定时器

ts 复制代码
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

ts 复制代码
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的类型使用到了typeoftypeof的作用是获取到initialState的类型定义

forwardRef & useImperativeHandle

这两个 Hook 组合一般用于在子组件定义事件,在父组件中调用,实现父子组件交互

js 复制代码
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;

子组件中接受两个参数propsref类型分别是propsTypeany(这里注意位置别搞混),暴露给父组件start方法,在父组件中想有语法提示,必须在声明ref的时候指定类型refType

useContext

ts 复制代码
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 键盘事件
ts 复制代码
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;
ts 复制代码
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 类型写得好可以提高代码质量,减少错误,增强代码的可维护性和可读性,从而提升整个项目的开发效率和稳定性

以上就是常见 Hook 的类型定义,如果有遗漏的欢迎大家评论留言,另外交给大家一个检验TS类型定义是否标准的一个方法,鼠标放在变量上看显示的类型是否跟数据的类型一致,而不是any

相关推荐
小牛itbull7 分钟前
ReactPress:重塑内容管理的未来
react.js·github·reactpress
逐·風3 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫4 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦4 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享6 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
清灵xmf7 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨7 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL8 小时前
npm入门教程1:npm简介
前端·npm·node.js