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";
|
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),
|
||||||
|
|||||||
Reference in New Issue
Block a user