mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-20 00:40:18 +00:00
Related to: https://github.com/tannerlinsley/react-table/issues/1657 Discussion: https://spectrum.chat/react-table/general/v7-maximum-update-depth-exceeded-usegroupby-useexpanded-with-usepagination~2c25e2b8-7a61-4c32-84b3-87db458701c2 Thanks to @iamjon for identifying usePagination was the culprit. I then checked the last changes made to it, and noticed it was previously listening to data and now it listened to rows (which I believe is a new reference on each render), causing infinite loop on one of its effects. I tested this change on my project and everything seems ok now.
164 lines
3.6 KiB
JavaScript
Executable File
164 lines
3.6 KiB
JavaScript
Executable File
import React from 'react'
|
|
|
|
//
|
|
import { addActions, actions } from '../actions'
|
|
import { defaultState } from '../hooks/useTable'
|
|
import { ensurePluginOrder, safeUseLayoutEffect, expandRows } from '../utils'
|
|
|
|
defaultState.pageSize = 10
|
|
defaultState.pageIndex = 0
|
|
|
|
addActions('pageChange', 'pageSizeChange')
|
|
|
|
export const usePagination = hooks => {
|
|
hooks.useMain.push(useMain)
|
|
}
|
|
|
|
usePagination.pluginName = 'usePagination'
|
|
|
|
const defaultGetResetPageDeps = ({
|
|
data,
|
|
manualPagination,
|
|
state: { filters, groupBy, sortBy },
|
|
}) => [manualPagination ? null : data, filters, groupBy, sortBy]
|
|
|
|
function useMain(instance) {
|
|
const {
|
|
rows,
|
|
manualPagination,
|
|
getResetPageDeps = defaultGetResetPageDeps,
|
|
manualExpandedKey = 'expanded',
|
|
debug,
|
|
plugins,
|
|
pageCount: userPageCount,
|
|
paginateExpandedRows = true,
|
|
expandSubRows = true,
|
|
state: { pageSize, pageIndex, expanded },
|
|
setState,
|
|
} = instance
|
|
|
|
ensurePluginOrder(
|
|
plugins,
|
|
['useFilters', 'useGroupBy', 'useSortBy', 'useExpanded'],
|
|
'usePagination',
|
|
[]
|
|
)
|
|
|
|
// Bypass any effects from firing when this changes
|
|
const isMountedRef = React.useRef()
|
|
safeUseLayoutEffect(() => {
|
|
if (isMountedRef.current) {
|
|
setState(
|
|
old => ({
|
|
...old,
|
|
pageIndex: 0,
|
|
}),
|
|
actions.pageChange
|
|
)
|
|
}
|
|
isMountedRef.current = true
|
|
}, [setState, ...(getResetPageDeps ? getResetPageDeps(instance) : [])])
|
|
|
|
const pageCount = manualPagination
|
|
? userPageCount
|
|
: Math.ceil(rows.length / pageSize)
|
|
|
|
const pageOptions = React.useMemo(
|
|
() => (pageCount > 0 ? [...new Array(pageCount)].map((d, i) => i) : []),
|
|
[pageCount]
|
|
)
|
|
|
|
const page = React.useMemo(() => {
|
|
let page
|
|
|
|
if (manualPagination) {
|
|
page = rows
|
|
} else {
|
|
if (process.env.NODE_ENV === 'development' && debug)
|
|
console.info('getPage')
|
|
|
|
const pageStart = pageSize * pageIndex
|
|
const pageEnd = pageStart + pageSize
|
|
|
|
page = rows.slice(pageStart, pageEnd)
|
|
}
|
|
|
|
if (paginateExpandedRows) {
|
|
return page
|
|
}
|
|
|
|
return expandRows(page, { manualExpandedKey, expanded, expandSubRows })
|
|
}, [
|
|
debug,
|
|
expandSubRows,
|
|
expanded,
|
|
manualExpandedKey,
|
|
manualPagination,
|
|
pageIndex,
|
|
pageSize,
|
|
paginateExpandedRows,
|
|
rows,
|
|
])
|
|
|
|
const canPreviousPage = pageIndex > 0
|
|
const canNextPage = pageCount === -1 || pageIndex < pageCount - 1
|
|
|
|
const gotoPage = React.useCallback(
|
|
updater => {
|
|
if (process.env.NODE_ENV === 'development' && debug)
|
|
console.info('gotoPage')
|
|
return setState(old => {
|
|
const newPageIndex =
|
|
typeof updater === 'function' ? updater(old.pageIndex) : updater
|
|
|
|
if (newPageIndex < 0 || newPageIndex > pageCount - 1) {
|
|
return old
|
|
}
|
|
return {
|
|
...old,
|
|
pageIndex: newPageIndex,
|
|
}
|
|
}, actions.pageChange)
|
|
},
|
|
[debug, pageCount, setState]
|
|
)
|
|
|
|
const previousPage = React.useCallback(() => {
|
|
return gotoPage(old => old - 1)
|
|
}, [gotoPage])
|
|
|
|
const nextPage = React.useCallback(() => {
|
|
return gotoPage(old => old + 1)
|
|
}, [gotoPage])
|
|
|
|
const setPageSize = React.useCallback(
|
|
pageSize => {
|
|
setState(old => {
|
|
const topRowIndex = old.pageSize * old.pageIndex
|
|
const pageIndex = Math.floor(topRowIndex / pageSize)
|
|
return {
|
|
...old,
|
|
pageIndex,
|
|
pageSize,
|
|
}
|
|
}, actions.pageSizeChange)
|
|
},
|
|
[setState]
|
|
)
|
|
|
|
return {
|
|
...instance,
|
|
pageOptions,
|
|
pageCount,
|
|
page,
|
|
canPreviousPage,
|
|
canNextPage,
|
|
gotoPage,
|
|
previousPage,
|
|
nextPage,
|
|
setPageSize,
|
|
pageIndex,
|
|
pageSize,
|
|
}
|
|
}
|