(logoIds = [])
| 86 | * Hook for components that need specific logos by IDs |
| 87 | */ |
| 88 | export const useLogosById = (logoIds = []) => { |
| 89 | const [isLoading, setIsLoading] = useState(false); |
| 90 | const [loadedIds, setLoadedIds] = useState(new Set()); |
| 91 | |
| 92 | const logos = useLogosStore((s) => s.logos); |
| 93 | const fetchLogosByIds = useLogosStore((s) => s.fetchLogosByIds); |
| 94 | |
| 95 | // Memoize missing IDs calculation to prevent infinite loops |
| 96 | const missingIds = useMemo(() => { |
| 97 | return logoIds.filter((id) => id && !logos[id] && !loadedIds.has(id)); |
| 98 | }, [logoIds, logos, loadedIds]); |
| 99 | |
| 100 | // Stringify logoIds to prevent array reference issues |
| 101 | const logoIdsString = logoIds.join(','); |
| 102 | |
| 103 | useEffect(() => { |
| 104 | if (missingIds.length > 0 && !isLoading) { |
| 105 | setIsLoading(true); |
| 106 | |
| 107 | // Track that we're loading these IDs to prevent re-requests |
| 108 | setLoadedIds((prev) => new Set([...prev, ...missingIds])); |
| 109 | |
| 110 | fetchLogosByIds(missingIds) |
| 111 | .then(() => setIsLoading(false)) |
| 112 | .catch((error) => { |
| 113 | console.error('Failed to load logos by IDs:', error); |
| 114 | // Remove failed IDs from loaded set so they can be retried |
| 115 | setLoadedIds((prev) => { |
| 116 | const newSet = new Set(prev); |
| 117 | missingIds.forEach((id) => newSet.delete(id)); |
| 118 | return newSet; |
| 119 | }); |
| 120 | setIsLoading(false); |
| 121 | }); |
| 122 | } |
| 123 | }, [logoIdsString, missingIds, isLoading, fetchLogosByIds]); |
| 124 | |
| 125 | return { |
| 126 | logos, |
| 127 | isLoading, |
| 128 | missingLogos: missingIds.length, |
| 129 | }; |
| 130 | }; |
no test coverage detected