reactjs - Anpassad Hook med generiska typer TypeScript
Jag har ett problem med att skapa gränssnitt till min egna hook usePagination. Jag behöver hjälp att skapa denna hook som generisk, eftersom gränssnittet User inte relaterar till de andra gränssnitten just nu. dataEntries är en array av användare med id, firstName och lastName. ElementsOnPage är satt till 50 som standard.
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,
},
]
}
Jag har försökt att göra något sådant här:
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
}
utan snarare skulle jag vilja hämta något liknande detta med hjälp av generiska typer:
function usePagination<T>(dataEntries: T[], elementsOnPage = 50): [PaginationState, PaginationActions] {
return [
{ actualPageIdx,
lastPageIdx,
entriesOnSelectedPage,
isBusy },
{
goToFirstPage,
goToPrevPage,
goToPage,
goToNextPage,
goToLastPage,
},
]
}
Svar #1
Du har nästan rätt. Du måste bara göra ditt PaginationState-gränssnitt generiskt:
interface PaginationState<T> {
lastPageIdx: number
actualPageIdx: number
entriesOnSelectedPage: () => T[]
isBusy: boolean
}
Och skicka sedan T till PaginationState i din usePagination-funktion.
function usePagination<T>(
dataEntries: T[],
elementsOnPage = 50
): [PaginationState<T>, PaginationActions] {
//...
}
Nu kan usePagination härleda dess generiska typ och föra den vidare till PaginationState<T>
const users: User[] = []
const [state, action] = usePagination(users) // state has type PaginationState<User>
Lekplats
