Skip to content

Refactor: move projectsWithSessions to Zustand store #23

@parsakhaz

Description

@parsakhaz

Problem

projectsWithSessions is local useState in DraggableProjectTreeView.tsx (~2500 lines). Every session status change creates a new array reference, which has caused infinite re-render loops in multiple useEffect hooks that depend on it. We've patched this twice now with refs:

  • 22ba70c - Diff panel infinite re-render (same pattern)
  • 453869d - DraggableProjectTreeView infinite re-render (3 effects)

The ref pattern works but is a symptom fix — the underlying issue is structural.

Root Cause

Event handlers and effects need access to the latest projectsWithSessions data, but including it in dependency arrays causes cascading re-renders because every update produces a new array reference. We currently work around this by syncing a useRef on every render, which is fragile and easy to forget when adding new effects.

Proposed Solution

Move projectsWithSessions into a Zustand store. This gives us:

  • Shallow selectors — components only re-render when the specific slice they subscribe to changes, not on every array reference change
  • getState() — event handlers can read current state directly without closures or refs
  • Single source of truth — no more local state + ref syncing pattern
  • Eliminates the class of bug entirely — new effects/handlers can't accidentally depend on a stale or re-triggering reference

Scope

  • Extract projectsWithSessions and archivedProjectsWithSessions state + all mutation logic from DraggableProjectTreeView.tsx into a new Zustand store (or extend sessionStore)
  • Update all IPC event handlers that call setProjectsWithSessions to use store actions instead
  • Remove the projectsWithSessionsRef / runningProjectIdRef workarounds
  • Components subscribe to specific slices with shallow comparison

Notes

This would also be a step toward breaking up the 2500-line DraggableProjectTreeView component, since the data layer would be decoupled from the UI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions