State Management - Incomplete-Infinity/eve-companion GitHub Wiki

🧠 State Management

This page outlines how application state is managed in the EVE Companion App using the Zustand library. Zustand provides a minimal, unopinionated store that is ideal for managing global state in modular apps like ours.


πŸ—ƒοΈ Why Zustand?

We chose Zustand because it:

  • Has a simple, hook-based API
  • Supports persistent and reactive state out of the box
  • Plays well with Electron, IndexedDB, and class-based patterns
  • Doesn’t require boilerplate or context providers

πŸ— Store Setup

Zustand stores are defined in individual files in the following folder:

src/js/stores/

Each store manages a slice of state related to a specific domain, such as:

  • Active character
  • Selected fit
  • UI layout preferences
  • Drag/drop window states

πŸ”„ Example Store

import { create } from 'zustand';

const useCharacterStore = create((set) => ({
  activeCharacterId: null,
  setActiveCharacter: (id) => set({ activeCharacterId: id })
}));

export default useCharacterStore;

Use inside a React component:

const characterId = useCharacterStore((s) => s.activeCharacterId);

πŸ“ Cross-Process Considerations

Zustand state lives in the renderer process and does not persist across restarts unless paired with:

  • electron-store β†’ persistent config values
  • dexie.js β†’ durable IndexedDB state (e.g. character cache)

πŸ” Reactive Updates

Zustand updates state reactively. Components or logic that subscribe to state changes will re-render when state is updated.

This works great for:

  • Toggling UI elements (windows, tabs)
  • Switching context (character, corp, region)
  • Live data visualization and updates

🧩 Integration Patterns

Pattern Use Case
Zustand only Volatile, UI-scoped state
Zustand + Dexie Cached live data from ESI (e.g., fits, types)
Zustand + electron-store Settings, preferences, login tokens

πŸ§ͺ Debugging Tips

  • Log state directly: console.log(useStore.getState())
  • Add devtools middleware if needed: import { devtools } from 'zustand/middleware'
  • Use selectors to avoid re-renders: useStore(state => state.key)

πŸ“Œ Summary

  • Zustand is our main state manager for renderer processes
  • Easy to integrate with persistent storage layers
  • Encourages composable and reactive UI behavior