The pagination-clamp useEffect added in #448 (commit 9c4a96f) was
inserted at the top of the component body, BEFORE the useQuery that
declares `data`. Because the useEffect's dependency array
`[data?.pagination, page]` is evaluated immediately when that line
executes, every render hit a temporal dead zone access on `data` and
threw `ReferenceError: Cannot access 'data' before initialization`
— minified to "Cannot access 'I' before initialization" in the
production bundle, crashing the entire page.
TypeScript caught this at the time
(`Block-scoped variable 'data' used before its declaration`) but the
project's build doesn't fail on TS errors so it shipped anyway.
Move the effect to immediately after the useQuery so `data` is in
scope. Behavior unchanged otherwise — same dep array, same setPage
clamp logic.
Reported by @derooijmnl on v3.45.1-beta.0.
This commit is contained in:
@@ -104,17 +104,6 @@ export const EventsListPage: React.FC = () => {
|
|||||||
setPage(1);
|
setPage(1);
|
||||||
}, [statusFilter, debouncedSearchTerm]);
|
}, [statusFilter, debouncedSearchTerm]);
|
||||||
|
|
||||||
// Clamp the active page when the result count shrinks (#442 — bulk
|
|
||||||
// delete of an entire page would leave the user on a now-empty
|
|
||||||
// page=N where N > totalPages, with no auto-correction). Triggers
|
|
||||||
// after each successful refetch when totalPages drops below the
|
|
||||||
// current page (bulk delete, individual delete, archive, anything).
|
|
||||||
useEffect(() => {
|
|
||||||
if (data?.pagination && page > data.pagination.totalPages) {
|
|
||||||
setPage(Math.max(1, data.pagination.totalPages));
|
|
||||||
}
|
|
||||||
}, [data?.pagination, page]);
|
|
||||||
|
|
||||||
// Close dropdown when clicking outside
|
// Close dropdown when clicking outside
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
@@ -157,6 +146,20 @@ export const EventsListPage: React.FC = () => {
|
|||||||
placeholderData: (prev) => prev,
|
placeholderData: (prev) => prev,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Clamp the active page when the result count shrinks (#442 — bulk
|
||||||
|
// delete of an entire page would leave the user on a now-empty
|
||||||
|
// page=N where N > totalPages, with no auto-correction). Triggers
|
||||||
|
// after each successful refetch when totalPages drops below the
|
||||||
|
// current page (bulk delete, individual delete, archive, anything).
|
||||||
|
// Must live AFTER the useQuery above so `data` is in scope — the
|
||||||
|
// original placement at the top of the component caused a TDZ
|
||||||
|
// ReferenceError on /admin/events that crashed the page (#454).
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.pagination && page > data.pagination.totalPages) {
|
||||||
|
setPage(Math.max(1, data.pagination.totalPages));
|
||||||
|
}
|
||||||
|
}, [data?.pagination, page]);
|
||||||
|
|
||||||
// Aggregate counters come from the dashboard stats endpoint so the cards
|
// Aggregate counters come from the dashboard stats endpoint so the cards
|
||||||
// and the "All (N)" filter button always reflect global totals, not the
|
// and the "All (N)" filter button always reflect global totals, not the
|
||||||
// currently visible page.
|
// currently visible page.
|
||||||
|
|||||||
Reference in New Issue
Block a user