Welcome back. In the previous unit, you wired up the game loop in GameScreen and, as a reminder, you added the TICK logic in the reducer to simulate time and events. In this lesson, you will complete that flow by handling win/loss transitions and rendering a dedicated results screen. The reducer will decide when the shift ends, and the UI will show performance stats and offer clean restart/navigation actions.
The reducer is the single source of truth for win/loss. It moves the app to the results screen and sets a result payload your UI can read.
src/reducers/gameReducer.js
Explanation:
- When the queue reaches max capacity, it sets
phasetoRESULTSand stores a failure result with a clear reason. - When time hits 0, it does one final update and sets a winning result.
- Both transitions also set
ui.screentoresultsso the UI knows which screen to render.
Now that the reducer sets phase, screen, and result, you can build a screen that reads state and presents the outcome with stats and actions.
src/components/ResultsScreen.js
Explanation:
- Reads
state.resultwith a safe fallback so the UI never crashes.
As a quick reminder, your GameScreen still drives the loop and can navigate to results on demand. This complements reducer-driven transitions and lets you end early.
src/components/GameScreen.js
Explanation:
- The
useEffect(from the prior unit) continues to dispatchTICKwhile playing and not paused. - The End Shift button uses
SET_SCREENto jump toresultsimmediately, which is useful for manual exits or testing.
You now have a clean win/loss flow:
- The reducer decides when the shift ends and sets a clear result object.
ResultsScreenreads that object, shows performance, and offers restart/navigation.- The game screen can also route to results when needed.
In the upcoming practice, you will polish this experience and make it feel great. Let’s put these transitions to work.
