具有通用类型 TypeScript 的自定义钩子 [英] Custom Hook with Generic Types TypeScript

查看:24
本文介绍了具有通用类型 TypeScript 的自定义钩子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在为自定义钩子 usePagination 制作接口时遇到问题.我需要帮助将这个钩子创建为通用的,因为此时接口 User 与其余接口无关.dataEntries 是具有 id、firstName 和 lastName 的用户数组.ElementsOnPage 默认设置为 50.

function usePagination(dataEntries,elementsOnPage = 50) {const [actualPageIdx, setActualPageIdx] = useState(1)const lastPageIdx = Math.ceil(dataEntries.length/elementsOnPage)const [isBusy, setIsBusy] = useState(false)const timeoutRef = useRef(null)useEffect(() => {setIsBusy(真)如果(timeoutRef.current){clearTimeout(timeoutRef.current)}timeoutRef.current = setTimeout(() => {setIsBusy(false)第 333 章}, [actualPageIdx])const entryOnSelectedPage = () =>{const firstEntry = (actualPageIdx - 1) * elementsOnPageconst lastEntry = firstEntry + elementsOnPageconsole.log(dataEntries.slice(firstEntry, lastEntry))返回 dataEntries.slice(firstEntry, lastEntry)}const goToFirstPage = useCallback(() => {setActualPageIdx(1)}, [])const goToLastPage = () =>{setActualPageIdx(lastPageIdx)}const goToPage = (page: number) =>{setActualPageIdx(页面)}const goToPrevPage = () =>{setActualPageIdx((actualPageIdx) => (actualPageIdx === 1 ? actualPageIdx : actualPageIdx - 1))}const goToNextPage = () =>{setActualPageIdx((actualPageIdx) =>actualPageIdx === lastPageIdx ?actualPageIdx : actualPageIdx + 1)}返回 [{ 实际PageIdx,lastPageIdx,entryOnSelectedPage,忙碌 },{转到第一页,转到上一页,转到页面,转到下一页,转到最后一页,},]}

我曾尝试这样做:

接口用户{身份证号码名字:字符串姓氏:字符串}接口分页状态{lastPageIdx:数字实际PageIdx:数字entryOnSelectedPage: () =>用户[]isBusy:布尔值}界面分页操作{goToFirstPage: () =>空白goToPrevPage: () =>空白goToNextPage: () =>空白goToLastPage: () =>空白goToPage: (number: number) =>空白}

而是我想使用泛型类型检索这样的东西:

function usePagination(dataEntries: T[], elementsOnPage = 50): [PaginationState, PaginationActions] {返回 [{ 实际PageIdx,lastPageIdx,entryOnSelectedPage,忙碌 },{转到第一页,转到上一页,转到页面,转到下一页,转到最后一页,},]}

解决方案

您几乎拥有它.你只需要让你的 PaginationState 接口通用:

interface PaginationState;{lastPageIdx:数字实际PageIdx:数字entryOnSelectedPage: () =>[]isBusy:布尔值}

然后将 T 传递给 usePagination 函数中的 PaginationState.

函数 usePagination(数据条目:T[],页面元素 = 50): [PaginationState<T>, PaginationActions] {//...}

现在 usePagination 可以推断它的泛型类型并将其传递给 PaginationState

const 用户:用户[] = []const [state, action] = usePagination(users)//状态类型为 PaginationState

游乐场

I have a problem with making interfaces to my custom hook usePagination. I need a help to create this hook as generic, because the interface User does'nt relate to rest of interfaces in this moment. dataEntries are array of users with id, firstName and lastName. ElementsOnPage is set to 50 as default.

function usePagination(dataEntries,elementsOnPage = 50) {
  const [actualPageIdx, setActualPageIdx] = useState(1)
  const lastPageIdx = Math.ceil(dataEntries.length / elementsOnPage)
  const [isBusy, setIsBusy] = useState(false)
  const timeoutRef = useRef<any>(null)


  useEffect(() => {
    setIsBusy(true)
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current)
    }
    timeoutRef.current = setTimeout(() => {
      setIsBusy(false)
    }, 333)
  }, [actualPageIdx])

  const entriesOnSelectedPage = () => {
    const firstEntry = (actualPageIdx - 1) * elementsOnPage
    const lastEntry = firstEntry + elementsOnPage
    console.log(dataEntries.slice(firstEntry, lastEntry))
    return dataEntries.slice(firstEntry, lastEntry)
  }

  const goToFirstPage = useCallback(() => {
    setActualPageIdx(1)
  }, [])

  const goToLastPage = () => {
    setActualPageIdx(lastPageIdx)
  }

  const goToPage = (page: number) => {
    setActualPageIdx(page)
  }

  const goToPrevPage = () => {
    setActualPageIdx((actualPageIdx) => (actualPageIdx === 1 ? actualPageIdx : actualPageIdx - 1))
  }

  const goToNextPage = () => {
    setActualPageIdx((actualPageIdx) =>
      actualPageIdx === lastPageIdx ? actualPageIdx : actualPageIdx + 1
    )
  }
 
  return [
    { actualPageIdx, 
      lastPageIdx, 
      entriesOnSelectedPage, 
      isBusy },
    {
      goToFirstPage,
      goToPrevPage,
      goToPage,
      goToNextPage,
      goToLastPage,
    },
  ]
}

I have tried to do sth like this:

interface User {
  id: number
  firstName: string
  lastName: string
}

interface PaginationState {
  lastPageIdx: number
  actualPageIdx: number
  entriesOnSelectedPage: () => User[]
  isBusy: boolean
}

interface PaginationActions {
  goToFirstPage: () => void
  goToPrevPage: () => void
  goToNextPage: () => void
  goToLastPage: () => void
  goToPage: (number: number) => void
}

but rather I would like to retrieve sth like this using generic types:

function usePagination<T>(dataEntries: T[], elementsOnPage = 50): [PaginationState, PaginationActions] {

  return [
    { actualPageIdx, 
      lastPageIdx, 
      entriesOnSelectedPage, 
      isBusy },
    {
      goToFirstPage,
      goToPrevPage,
      goToPage,
      goToNextPage,
      goToLastPage,
    },
  ]
}

解决方案

You almost have it. You just have to make your PaginationState interface generic:

interface PaginationState<T> {
  lastPageIdx: number
  actualPageIdx: number
  entriesOnSelectedPage: () => T[]
  isBusy: boolean
}

And then pass T to PaginationState in your usePagination function.

function usePagination<T>(
  dataEntries: T[],
  elementsOnPage = 50
): [PaginationState<T>, PaginationActions] {
  //...
}

Now usePagination can infer it's generic type and pass it along through to PaginationState<T>

const users: User[] = []
const [state, action] = usePagination(users) // state has type PaginationState<User>

Playground

这篇关于具有通用类型 TypeScript 的自定义钩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆