fix(app): cache useFavorites snapshot to prevent infinite re-render

This commit is contained in:
2026-07-11 22:39:46 +02:00
parent bb4d07055f
commit 6912653906

View File

@@ -3,14 +3,20 @@ import { useCallback, useSyncExternalStore } from "react";
const STORAGE_KEY = "favorites"; const STORAGE_KEY = "favorites";
let listeners: Array<() => void> = []; let listeners: Array<() => void> = [];
let cachedRaw: string | null = null;
let cachedParsed: string[] = [];
function getSnapshot(): string[] { function getSnapshot(): string[] {
try { try {
const raw = localStorage.getItem(STORAGE_KEY); const raw = localStorage.getItem(STORAGE_KEY);
return raw ? JSON.parse(raw) : []; if (raw !== cachedRaw) {
cachedRaw = raw;
cachedParsed = raw ? JSON.parse(raw) : [];
}
} catch { } catch {
return []; cachedParsed = [];
} }
return cachedParsed;
} }
function subscribe(cb: () => void) { function subscribe(cb: () => void) {
@@ -20,12 +26,18 @@ function subscribe(cb: () => void) {
}; };
} }
const EMPTY: string[] = [];
function getServerSnapshot(): string[] {
return EMPTY;
}
function notify() { function notify() {
cachedRaw = null;
listeners.forEach((l) => l()); listeners.forEach((l) => l());
} }
export function useFavorites() { export function useFavorites() {
const favorites = useSyncExternalStore(subscribe, getSnapshot, () => []); const favorites = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
const isFavorite = useCallback( const isFavorite = useCallback(
(id: string) => favorites.includes(id), (id: string) => favorites.includes(id),