fix(app): cache useFavorites snapshot to prevent infinite re-render
This commit is contained in:
@@ -3,14 +3,20 @@ import { useCallback, useSyncExternalStore } from "react";
|
||||
const STORAGE_KEY = "favorites";
|
||||
|
||||
let listeners: Array<() => void> = [];
|
||||
let cachedRaw: string | null = null;
|
||||
let cachedParsed: string[] = [];
|
||||
|
||||
function getSnapshot(): string[] {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
return raw ? JSON.parse(raw) : [];
|
||||
if (raw !== cachedRaw) {
|
||||
cachedRaw = raw;
|
||||
cachedParsed = raw ? JSON.parse(raw) : [];
|
||||
}
|
||||
} catch {
|
||||
return [];
|
||||
cachedParsed = [];
|
||||
}
|
||||
return cachedParsed;
|
||||
}
|
||||
|
||||
function subscribe(cb: () => void) {
|
||||
@@ -20,12 +26,18 @@ function subscribe(cb: () => void) {
|
||||
};
|
||||
}
|
||||
|
||||
const EMPTY: string[] = [];
|
||||
function getServerSnapshot(): string[] {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
function notify() {
|
||||
cachedRaw = null;
|
||||
listeners.forEach((l) => l());
|
||||
}
|
||||
|
||||
export function useFavorites() {
|
||||
const favorites = useSyncExternalStore(subscribe, getSnapshot, () => []);
|
||||
const favorites = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
|
||||
const isFavorite = useCallback(
|
||||
(id: string) => favorites.includes(id),
|
||||
|
||||
Reference in New Issue
Block a user