From e7723cd223ddd41758a2a1f34aab4353e3708b13 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 22 Jan 2026 15:03:08 +0000 Subject: [PATCH] fix: call useReqTimelineEnhanced unconditionally to follow Rules of Hooks - Always call useReqTimelineEnhanced hook regardless of conditions - Use shouldFetch flag to determine whether to actually fetch - Pass disabled ID and empty arrays when not fetching - Fixes 'Rendered more hooks than during the previous render' error --- src/components/EventDetailViewer.tsx | 21 ++++++++------------- src/components/ProfileViewer.tsx | 21 ++++++++------------- src/components/RelayViewer.tsx | 22 ++++++++-------------- 3 files changed, 24 insertions(+), 40 deletions(-) diff --git a/src/components/EventDetailViewer.tsx b/src/components/EventDetailViewer.tsx index a9092e9..fa254d5 100644 --- a/src/components/EventDetailViewer.tsx +++ b/src/components/EventDetailViewer.tsx @@ -175,19 +175,14 @@ function SpellTabContent({ }, [parsed?.relays, targetEvent, spell.name, spellId]); // Fetch events using the applied filter - const { events, loading, eoseReceived } = - appliedFilter && finalRelays.length > 0 - ? useReqTimelineEnhanced( - `spell-${spellId}-${targetEventId}`, - appliedFilter, - finalRelays, - { limit: appliedFilter.limit || 50, stream: true }, - ) - : { - events: [], - loading: false, - eoseReceived: false, - }; + // Always call the hook unconditionally (React Rules of Hooks) + const shouldFetch = !!(appliedFilter && finalRelays.length > 0); + const { events, loading, eoseReceived } = useReqTimelineEnhanced( + shouldFetch ? `spell-${spellId}-${targetEventId}` : `disabled-${spellId}`, + appliedFilter || {}, + shouldFetch ? finalRelays : [], + { limit: appliedFilter?.limit || 50, stream: true }, + ); console.log(`[EventSpell:${spell.name || spellId}] Render state:`, { hasFilter: !!appliedFilter, diff --git a/src/components/ProfileViewer.tsx b/src/components/ProfileViewer.tsx index b778abb..d218a8f 100644 --- a/src/components/ProfileViewer.tsx +++ b/src/components/ProfileViewer.tsx @@ -219,19 +219,14 @@ function SpellTabContent({ ]); // Fetch events using the applied filter - const { events, loading, eoseReceived } = - appliedFilter && finalRelays.length > 0 - ? useReqTimelineEnhanced( - `spell-${spellId}-${targetPubkey}`, - appliedFilter, - finalRelays, - { limit: appliedFilter.limit || 50, stream: true }, - ) - : { - events: [], - loading: false, - eoseReceived: false, - }; + // Always call the hook unconditionally (React Rules of Hooks) + const shouldFetch = !!(appliedFilter && finalRelays.length > 0); + const { events, loading, eoseReceived } = useReqTimelineEnhanced( + shouldFetch ? `spell-${spellId}-${targetPubkey}` : `disabled-${spellId}`, + appliedFilter || {}, + shouldFetch ? finalRelays : [], + { limit: appliedFilter?.limit || 50, stream: true }, + ); console.log(`[SpellTabContent:${spell.name || spellId}] Render state:`, { hasFilter: !!appliedFilter, diff --git a/src/components/RelayViewer.tsx b/src/components/RelayViewer.tsx index 566b700..20a6f31 100644 --- a/src/components/RelayViewer.tsx +++ b/src/components/RelayViewer.tsx @@ -148,21 +148,15 @@ function SpellTabContent({ }, [parsed?.relays, targetRelay, spell.name, spellId]); // Fetch events using the applied filter + // Always call the hook unconditionally (React Rules of Hooks) + const shouldFetch = !!(appliedFilter && finalRelays.length > 0); const { events, loading, eoseReceived, relayStates, overallState } = - appliedFilter && finalRelays.length > 0 - ? useReqTimelineEnhanced( - `spell-${spellId}-${targetRelay}`, - appliedFilter, - finalRelays, - { limit: appliedFilter.limit || 50, stream: true }, - ) - : { - events: [], - loading: false, - eoseReceived: false, - relayStates: new Map(), - overallState: undefined, - }; + useReqTimelineEnhanced( + shouldFetch ? `spell-${spellId}-${targetRelay}` : `disabled-${spellId}`, + appliedFilter || {}, + shouldFetch ? finalRelays : [], + { limit: appliedFilter?.limit || 50, stream: true }, + ); // Convert relay states to the format expected by SpellHeader const reqRelayStatesMap = useMemo(() => {