Replace ref+tick workaround with proper state in useBestiary
Store creature map in useState instead of useRef with a dummy tick counter. React now re-renders naturally when the map changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@ import type {
|
|||||||
Creature,
|
Creature,
|
||||||
CreatureId,
|
CreatureId,
|
||||||
} from "@initiative/domain";
|
} from "@initiative/domain";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
normalizeBestiary,
|
normalizeBestiary,
|
||||||
setSourceDisplayNames,
|
setSourceDisplayNames,
|
||||||
@@ -33,8 +33,9 @@ interface BestiaryHook {
|
|||||||
|
|
||||||
export function useBestiary(): BestiaryHook {
|
export function useBestiary(): BestiaryHook {
|
||||||
const [isLoaded, setIsLoaded] = useState(false);
|
const [isLoaded, setIsLoaded] = useState(false);
|
||||||
const creatureMapRef = useRef<Map<CreatureId, Creature>>(new Map());
|
const [creatureMap, setCreatureMap] = useState(
|
||||||
const [, setTick] = useState(0);
|
() => new Map<CreatureId, Creature>(),
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const index = loadBestiaryIndex();
|
const index = loadBestiaryIndex();
|
||||||
@@ -44,8 +45,7 @@ export function useBestiary(): BestiaryHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bestiaryCache.loadAllCachedCreatures().then((map) => {
|
bestiaryCache.loadAllCachedCreatures().then((map) => {
|
||||||
creatureMapRef.current = map;
|
setCreatureMap(map);
|
||||||
setTick((t) => t + 1);
|
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -63,9 +63,12 @@ export function useBestiary(): BestiaryHook {
|
|||||||
}));
|
}));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getCreature = useCallback((id: CreatureId): Creature | undefined => {
|
const getCreature = useCallback(
|
||||||
return creatureMapRef.current.get(id);
|
(id: CreatureId): Creature | undefined => {
|
||||||
}, []);
|
return creatureMap.get(id);
|
||||||
|
},
|
||||||
|
[creatureMap],
|
||||||
|
);
|
||||||
|
|
||||||
const isSourceCachedFn = useCallback(
|
const isSourceCachedFn = useCallback(
|
||||||
(sourceCode: string): Promise<boolean> => {
|
(sourceCode: string): Promise<boolean> => {
|
||||||
@@ -86,10 +89,13 @@ export function useBestiary(): BestiaryHook {
|
|||||||
const creatures = normalizeBestiary(json);
|
const creatures = normalizeBestiary(json);
|
||||||
const displayName = getSourceDisplayName(sourceCode);
|
const displayName = getSourceDisplayName(sourceCode);
|
||||||
await bestiaryCache.cacheSource(sourceCode, displayName, creatures);
|
await bestiaryCache.cacheSource(sourceCode, displayName, creatures);
|
||||||
for (const c of creatures) {
|
setCreatureMap((prev) => {
|
||||||
creatureMapRef.current.set(c.id, c);
|
const next = new Map(prev);
|
||||||
}
|
for (const c of creatures) {
|
||||||
setTick((t) => t + 1);
|
next.set(c.id, c);
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -100,18 +106,20 @@ export function useBestiary(): BestiaryHook {
|
|||||||
const creatures = normalizeBestiary(jsonData as any);
|
const creatures = normalizeBestiary(jsonData as any);
|
||||||
const displayName = getSourceDisplayName(sourceCode);
|
const displayName = getSourceDisplayName(sourceCode);
|
||||||
await bestiaryCache.cacheSource(sourceCode, displayName, creatures);
|
await bestiaryCache.cacheSource(sourceCode, displayName, creatures);
|
||||||
for (const c of creatures) {
|
setCreatureMap((prev) => {
|
||||||
creatureMapRef.current.set(c.id, c);
|
const next = new Map(prev);
|
||||||
}
|
for (const c of creatures) {
|
||||||
setTick((t) => t + 1);
|
next.set(c.id, c);
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const refreshCache = useCallback(async (): Promise<void> => {
|
const refreshCache = useCallback(async (): Promise<void> => {
|
||||||
const map = await bestiaryCache.loadAllCachedCreatures();
|
const map = await bestiaryCache.loadAllCachedCreatures();
|
||||||
creatureMapRef.current = map;
|
setCreatureMap(map);
|
||||||
setTick((t) => t + 1);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user