State Management

Patterns for local state, derived data, and cross-collection composition in Routier applications.

Overview

State management in Routier involves managing application state through collections, live queries, and derived data. Routier provides built-in features that make state management straightforward and efficient.

Key Concepts

Collections as State

Collections act as your primary state containers:

class AppContext extends DataStore {
  users = this.collection(userSchema).create();
  products = this.collection(productSchema).create();
}

Live Queries

Keep UI in sync with data changes automatically:

ctx.users.subscribe().toArray((result) => {
  if (result.ok === "success") {
    console.log("Users:", result.data); // Automatically updates when users change
  }
});

Note: With .subscribe(), you must use callback-based methods (not async methods like toArrayAsync()).

Change Tracking

All modifications are tracked automatically until saved:

user.name = "New Name"; // Tracked automatically
await ctx.saveChangesAsync(); // Persisted

Derived State

Compute derived data from your collections:

const stats = {
  totalUsers: await ctx.users.countAsync(),
  activeUsers: await ctx.users.where((u) => u.isActive).countAsync(),
};

Patterns

  • Single Source of Truth: Collections serve as your data source
  • Automatic Updates: Live queries keep UI in sync
  • Explicit Persistence: Changes saved with saveChangesAsync()
  • Type Safety: Full TypeScript support