【问题标题】:Custom Hook with Generic Types TypeScript使用通用类型 TypeScript 的自定义 Hook
【发布时间】:2020-08-31 16:01:13
【问题描述】:

我在为我的自定义钩子 usePagination 创建接口时遇到问题。我需要帮助来将此钩子创建为通用的,因为此时用户接口与其余接口无关。 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<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,
    },
  ]
}

我尝试过这样做:

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
}

但我想使用泛型类型来检索这样的东西:

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

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

【问题讨论】:

    标签: reactjs typescript react-hooks


    【解决方案1】:

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

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

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

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

    现在usePagination 可以推断它是泛型类型并将其传递给PaginationState&lt;T&gt;

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

    Playground

    【讨论】:

    • 谢谢,这对我很有帮助,但我遇到了错误。请看我的第二个帖子!
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 2020-01-15
    • 2021-01-24
    • 2020-11-11
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    相关资源
    最近更新 更多