fix: ChargeabilityWidget hooks order — move useMemo before early return

React Rules of Hooks violation: filteredTop and filteredWatch useMemo
hooks were placed AFTER the isLoading early return, causing "Rendered
more hooks than during the previous render" error that crashed the
entire dashboard.

Fix: moved rawTop/rawWatch/month declarations and filteredTop/filteredWatch
useMemo hooks BEFORE the isLoading early return so hooks always run
in the same order.

Verified in Chrome: dashboard loads with zero console errors.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-03-23 09:36:37 +01:00
parent bc6afefeae
commit ea9263de29
@@ -145,6 +145,23 @@ export function ChargeabilityWidget({ config: _config, onConfigChange }: WidgetP
setWatchVisibleCount(batchSize);
}, [batchSize, includeProposed, selectedCountryIds, showDeparted]);
// These useMemo hooks MUST be before any early return to respect Rules of Hooks
const rawTop = data?.top ?? [];
const rawWatch = data?.watchlist ?? [];
const month = (data?.month as string) ?? "";
const filteredTop = useMemo(() => {
const arr = rawTop as ChargeabilityRow[];
if (!chapterFilter) return arr;
return arr.filter((r) => r.chapter === chapterFilter);
}, [rawTop, chapterFilter]);
const filteredWatch = useMemo(() => {
const arr = rawWatch as ChargeabilityRow[];
if (!chapterFilter) return arr;
return arr.filter((r) => r.chapter === chapterFilter);
}, [rawWatch, chapterFilter]);
if (isLoading) {
return (
<div className="flex flex-col gap-3 pt-1">
@@ -171,22 +188,6 @@ export function ChargeabilityWidget({ config: _config, onConfigChange }: WidgetP
);
}
const rawTop = data?.top ?? [];
const rawWatch = data?.watchlist ?? [];
const month = (data?.month as string) ?? "";
const filteredTop = useMemo(() => {
const arr = rawTop as ChargeabilityRow[];
if (!chapterFilter) return arr;
return arr.filter((r) => r.chapter === chapterFilter);
}, [rawTop, chapterFilter]);
const filteredWatch = useMemo(() => {
const arr = rawWatch as ChargeabilityRow[];
if (!chapterFilter) return arr;
return arr.filter((r) => r.chapter === chapterFilter);
}, [rawWatch, chapterFilter]);
const top = ([...filteredTop]).sort((a, b) => {
const mult = topDir === "asc" ? 1 : -1;
switch (topSort) {