[英]Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop
[英]Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop in pagination
我在表格中有一個數據,我想向它添加一個分頁選項。 在用戶界面中,用戶應該能夠選擇每頁的數據和頁面索引,這就是為什么我向它添加了一些句柄方法並嘗試渲染它,但我遇到了上述錯誤。
整個 jsx 文件太長,無法共享,因此我只共享對我來說很重要的代碼,並將其他代碼替換為...如果您需要其他任何內容,可以在評論中提出。
function Activity(props) {
...
const variables = useMemo(() => ({
projectId,
language,
env: environment,
pageSize: 20,
filter,
...getSortFunction(),
}), [projectId, language, environment, filter, getSortFunction()]);
const {
data, hasNextPage, loading, loadMore, refetch,
} = useActivity(variables);
//pagination section
const [pagination, setPagination] = useState({
currentPage: 1,
dataPerPage: 10,
indexOfLastData: 9,
indexOfFirstData: 0,
})
const [totalPages, setTotalPages] = useState(1);
const [paginationString, setPaginationString] = useState(`Current page ${pagination.currentPage}, total number of data ${pagination.dataPerPage}`)
const handlePagination = (page, dataPerPage, currentPagination) => {
if (currentPagination.currentPage != page) handlePaginationCurrentPage(page, currentPagination);
if (currentPagination.dataPerPage != dataPerPage) handlePaginationDataPerPage(dataPerPage, currentPagination);
const dataToBeUsed = [...data].slice(pagination.indexOfFirstData, pagination.indexOfLastData);
setTotalPages(Math.ceil(3 / pagination.dataPerPage));
return dataToBeUsed;
}
const handlePaginationString = () => {
setPaginationString(`current page ${pagination.currentPage}, total number of data ${pagination.dataPerPage}`)
}
const handlePaginationCurrentPage = (page, pagination) => {
useEffect(() => {
setPagination({
...pagination,
currentPage: Number(page),
indexOfLastData: pagination.dataPerPage * Number(page) - 1,
indexOfFirstData: pagination.dataPerPage * Number(page) - pagination.dataPerPage
})
})
}
const handlePaginationDataPerPage = (dataPerPage, pagination) => {
useEffect(() => {
setPagination({
...pagination,
dataPerPage: dataPerPage,
indexOfLastData: dataPerPage * pagination.currentPage - 1,
indexOfFirstData: dataPerPage * pagination.currentPage - pagination.dataPerPage
})
})
}
const resetPagination = (e) => {
e.stopPropagation();
handlePagination(1, 10, pagination);
};
...
const renderActions = row => (
<ActivityActionsColumn
outdated={ isUtteranceOutdated(row.datum) }
datum={ row.datum }
handleSetValidated={ handleSetValidated }
onDelete={ handleDelete }
onMarkOoS={ handleMarkOoS }
data={ handlePagination(1, 10, pagination) }
getSmartTips={ utterance => getSmartTips({
nluThreshold, endTime, examples, utterance,
}) }
/>
);
...
const columns = [
{ key: '_id', selectionKey: true, hidden: true },
{
key: 'confidence',
style: { width: '51px', minWidth: '51px' },
render: renderConfidence,
},
{
key: 'intent',
style: { width: '180px', minWidth: '180px', overflow: 'hidden' },
render: renderIntent,
},
{
key: 'conversation-popup', style: { width: '30px', minWidth: '30px' }, render: renderConvPopup,
},
{
key: 'text',
style: { width: '100%' },
render: renderExample,
},
...(can('incoming:w', projectId) ? [
{
key: 'actions',
style: { width: '110px' },
render: renderActions,
},
] : []),
];
const renderTopBar = () => (
<div className='side-by-side wrap' style={ { marginBottom: '10px' } }>
...
<Accordion className='pagination-accordion'>
<Accordion.Title
active={ activeAccordion }
onClick={ () => handleAccordionClick() }
data-cy='toggle-pagination'
className='pagination-accordian-title'
>
<Icon name='dropdown' />
<span className='toggle-pagination'>
{ activeAccordion
? `Hide Pagination Options `
: `Show Pagination Options ` }
</span>
<span className="toggle-pagination pagination-string">
{ activeAccordion
? `${paginationString}`
: `${paginationString}` }
</span>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */ }
<span
data-cy='reset-pagination'
onClick={ e => resetPagination(e) }
role='button'
tabIndex='0'
className='reset-button'
>
<Icon name='redo' size='small' /> Reset
</span>
</Accordion.Title>
</Accordion>
</div>
);
return (
<>
{ !!openConvPopup && <ConversationSidePanel utterance={ openConvPopup } onClose={ () => setOpenConvPopup(false) } /> }
{ renderTopBar() }
{ data && data.length ? (
<>
<DataTable
ref={ tableRef }
columns={ columns }
data={ handlePagination(1, 10, pagination) }
hasNextPage={ hasNextPage }
loadMore={ loading ? () => { } : loadMore }
onScroll={ handleScroll }
selection={ selection }
onChangeSelection={ (newSelection) => {
setSelection(newSelection);
setOpenConvPopup(false);
} }
/>
)}
我不能在分頁中使用數據,因為它在很多地方都使用過,並且在那些地方,所有設計的假設數據都是全長的,所以我應該單獨使用它(例如/在 handlePagination 中我使用 data.slice() function)
謝謝!
我變了
<DataTable
ref={ tableRef }
columns={ columns }
data={ handlePagination(1, 10, pagination) }
hasNextPage={ hasNextPage }
loadMore={ loading ? () => { } : loadMore }
onScroll={ handleScroll }
selection={ selection }
onChangeSelection={ (newSelection) => {
setSelection(newSelection);
setOpenConvPopup(false);
} }
/>
至
<DataTable
ref={ tableRef }
columns={ columns }
data={ dataToBeShowed }
hasNextPage={ hasNextPage }
loadMore={ loading ? () => { } : loadMore }
onScroll={ handleScroll }
selection={ selection }
onChangeSelection={ (newSelection) => {
setSelection(newSelection);
setOpenConvPopup(false);
} }
/>
並添加
const [dataToBeShowed, setDataToBeShowed] = useState(data.slice(pagination.indexOfFirstData, pagination.indexOfLastData));
useEffect(() => {
setDataToBeShowed(data.slice(pagination.indexOfFirstData, pagination.indexOfLastData));
setPaginationString(`Current page ${pagination.currentPage}, total number of data ${pagination.dataPerPage}`)
setTotalPages(Math.ceil(data.length / pagination.dataPerPage));
}, [data, pagination.indexOfFirstData, pagination.indexOfLastData]);
這解決了,因為我看到 handlePagination(1, 10, pagination) 不在 Activity 中呈現,而是在 Window 中呈現,這意味着它看不到狀態,因此我添加了 dataToBeShown 並將其分配給真實數據,因為我添加了 useEffect,它跟隨數據(真實數據)的變化。
(如果您使用 onClick 與您可以簡單地添加 () => {handleOnBruh()} 相比,它會以這種方式將自身與文件綁定。)
謝謝!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.