diff --git a/src/features/store-admin/HealthScorePanel.tsx b/src/features/store-admin/HealthScorePanel.tsx index e4d82bc..f05634a 100644 --- a/src/features/store-admin/HealthScorePanel.tsx +++ b/src/features/store-admin/HealthScorePanel.tsx @@ -56,14 +56,25 @@ export function HealthScorePanel({ populated for both, so nothing in the response separates them. Our own category does, so the decision is made here until they publish theirs. - Before the network call, deliberately: there is nothing to ask about. + Still no network call for one — see `enabled` below — but the EARLY RETURN + that used to sit here has moved past the hook. + + It read `if (!isEdible(category)) return null` on the line above `useQuery`, + which made the hook conditional. React counts hooks per component instance, so + one drawer reused for two products — a soap and then a biscuit, which is + ordinary browsing in the global catalogue — went 0 hooks then 1, and React + threw "rendered more hooks than during the previous render". That does not + degrade the panel, it unmounts the tree: the health score then disappears for + EVERY product until the page is reloaded, which reads exactly like the feature + being switched off. */ - if (!isEdible(category)) return null; + const isFood = isEdible(category); const query = useQuery({ queryKey: ['nutrition', brand, imageId], queryFn: () => nutritionApi.forProduct(brand, imageId), - enabled: Boolean(brand && imageId), + // Non-food asks nothing, which is what the early return was protecting. + enabled: Boolean(brand && imageId && isFood), // Nutrition for a packaged product does not change during a trading day. staleTime: 60 * 60_000, refetchOnWindowFocus: false, @@ -72,6 +83,9 @@ export function HealthScorePanel({ retry: false, }); + // Past the hook, so the count is the same on every render. + if (!isFood) return null; + /* * No catalogue link, so there is nothing to look up. *