Skip to content

Code Review Phase 4: Redux Store, Slices & Selectors #25

@jitu5

Description

@jitu5

Code Review Phase 4: Redux Store, Slices & Selectors

Purpose: Review the state management layer — the nervous system of the app. Every slice follows the same normalized { byId, allIds } pattern, and selectors use createSelector for memoization.

Prerequisites: Phases 1-3 (Types, Constants, Domain Layer)
Estimated time: 2 hours
Files: 20


Architecture Diagram

Redux Data Flow:

Component ──dispatch(action)──▶ Reducer ──▶ New State ──▶ Selector ──▶ Component
                                   │                        ▲
                                   │                        │
                                   ▼                   (memoized via
                            autoSaveMiddleware          createSelector)
                                   │
                                   ▼
                             localStorage

Normalized State Shape (each entity slice):
┌─────────────────────────────────┐
│ { byId: { "node-1": {...},     │  ◀── O(1) lookup by ID
│           "node-2": {...} },   │
│   allIds: ["node-1","node-2"], │  ◀── Iteration order
│   selected: ["node-1"] }       │  ◀── Multi-select tracking
└─────────────────────────────────┘

Files to Review (in order)

Store Setup

Feature Slices

Tests


Key Concepts

  • Redux Toolkit's createSlice uses Immer under the hood, so "mutating" code like state.byId[id] = node is actually producing immutable updates
  • The prepare callback in addNode/addDataset enables action creators to accept flexible inputs and normalize them before reaching the reducer
  • createSelector from RTK memoizes selectors — they only recompute when input selectors return new references
  • selectSelectedNodeIdsSet creates a Set from the array for O(1) lookups in hot render paths

Focus Areas

  • Verify reducers are pure: uiSlice.ts no longer calls localStorage.setItem() directly — persistence is handled by autoSaveMiddleware. themeSlice.ts only reads localStorage at initialization time via safeGetItem(STORAGE_KEYS.THEME). Confirm no new side effects have crept in.
  • Both uiSlice and themeSlice now use STORAGE_KEYS constants. Verify consistency.
  • deleteNodes and deleteDatasets now use Set for O(n) complexity. Verify the Set-based implementation is correct.
  • Are createSelector-based selectors properly memoized when called with inline parameters?
  • autoSaveMiddleware uses module-level let saveTimeout — is this safe with hot module replacement?
  • The theme selector was split out of the canvas mega-selector into its own standalone selector. Verify this doesn't break theme-dependent components.
  • Review slice tests — do they cover edge cases like deleting non-existent nodes, selecting already-selected items, empty state operations?
  • Review middleware tests — do they verify debounce timing and action filtering?

Next: Phase 5 (Persistence & Telemetry)

Metadata

Metadata

Assignees

No one assigned

    Labels

    code-reviewStructured code review phases

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions