热搜:fiddler git ip ios 代理
历史搜索

提升React开发效率:掌握这些必备Hook类型定义

游客2024-08-05 14:33:01
目录文章目录
  1. useState
  2. useRef
  3. useReducer
  4. forwardRef 与 useImperativeHandle
  5. useContext
  6. 事件类型
  7. 总结

最近在做 React 项目时,使用 TS 语言结合开发,第一次尝试在 React 项目中用 TS 写,总结了一些常见的 Hook 类型定义的笔记,希望能帮助到大家,一起看一下吧。

提升React开发效率:掌握这些必备Hook类型定义 1

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是自定义的类型,意思是对象里面有两个参数nameageage可以为空(?是指可空)。

useState<userType | null>()Hook 的返回值是userType类型或null,因为初始值null,所以usernull,这样使用到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的类型使用到了typeoftypeof的作用是获取到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;

子组件中接受两个参数propsref类型分别是propsTypeany(这里注意位置别搞混),暴露给父组件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