Skip to content

slideroom/fw-state

 
 

Repository files navigation

State management

Handle your state with typed actions.

Features

  • Async dispatches
  • Typed actions (to request a change of state)
  • Stores are classes
  • Made for DI Containers via interface
  • Listen for store changes

Quick Example

Define an action:

export class LoginAction {
  constructor(public userName: string, public password: string) {}
}

Define a store:

import { Store, handle } from "fw-state";

// the file that the above action is defined in...
import { LoginAction } from "./actions"; 

export class MyStore1 extends Store<{ loggedIn: boolean }> {
  defaultState() {
    return {
      loggedIn: false,
    };
  }

  @handle(LoginAction)
  private async handleLogin(action: LoginAction) {
    // you can await network calls here..  or perform other logic

    // if you want too, throw
    if (someError) {
      throw new Error("Could not log in");
    }

    // when you are satisfied, you can update the state of this store..
    this.setState(state => ({
      ...state,
      loggedIn: true,
    }));
  }
}

Before you can dispatch to stores, you must set them up.

import { setupStores } from "fw-state";

setupStores(containerInstance,
  MyStore1,
  MyStore2,
);

Now we can dispatch:

import { dispatch } from "fw-state";
import { LoginAction } from "./actions";

await dispatch(new LoginAction("user", "password"));

You can await your dispatch (if you want) or just fire and forget..

Dispatching will call all of the handlers on every store that handles it.

Example:

// in your actions
export class LogoutAction {}


// in a store:
// ....

  @handle(LogoutAction)
  private handleLogout() {
    this.setState(_ => this.defaultState());
  }

// ....

You can imagine that if you have a lot of different stores containing data, dispatching one action to reset every stores' state is ideal.

Accessing state

const myStore1 = containerInstance.get(MyStore1);

const { loggedIn } = myStore1.state;
console.log(loggedIn ? "Hi!!" : "Please Log In");

Listen for changes

If you need to, you can manually listen to changes with:

const myStore1 = containerInstance.get(MyStore1);

const disposer = myStore1.onStateChanged(() => {
  // state changed
});

// when you are done:
disposer.dispose();

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 80.2%
  • JavaScript 19.8%