diff --git a/src/components/GameProvider.tsx b/src/components/GameProvider.tsx index 53c3b79..964c761 100644 --- a/src/components/GameProvider.tsx +++ b/src/components/GameProvider.tsx @@ -30,7 +30,7 @@ export default function GameProvider() { const [showLevelNavigator, setShowLevelNavigator] = useState(false); const [isPanelCollapsed, setIsPanelCollapsed] = useState(false); const [promotionRank, setPromotionRank] = useState(null); - const prevRankRef = useRef(null); + const [prevRank, setPrevRank] = useState(null); const rightPanelRef = useRef(null); const { currentLevel, totalXp, currentStreak, rehydrateFleet } = useGameStore(); @@ -38,13 +38,14 @@ export default function GameProvider() { // so every rank up to Managing Director is actually reachable. const rank = rankInfo(totalXp); - // Detect rank promotions and surface the banner. - useEffect(() => { - if (prevRankRef.current !== null && prevRankRef.current !== rank.name) { + // Detect rank promotions and surface the banner. State is adjusted during + // render (not in an effect) per https://react.dev/learn/you-might-not-need-an-effect + if (prevRank !== rank.name) { + if (prevRank !== null) { setPromotionRank(rank.name); } - prevRankRef.current = rank.name; - }, [rank.name]); + setPrevRank(rank.name); + } useEffect(() => { initDatabase()