Staterx Docs
StateRxQuick StartInstallCounter ExampleEffectsReact Example
Guides
Api
Examples

Quick Start

Install

npm i staterx rxjs or yarn add staterx rxjs

Counter Example

import { createValue } from 'staterx';
// create a counter
// counter holds a value and a basic api
// get, set, reset, and state$
const counter = createValue({default: 0});
console.log(counter.get()); // logs 0
counter.set(1); // update the value
console.log(counter.get()); // logs 1

In the most basic example, we have a single value that we are creating and updating imperatively. RxJS natives are probably thinking "isn't this just a Behavior Subject?" Obviously in this contrived example, it's not obvious that we have any benefit over using a regular variable.

The real power of this example is that we actualy just created a stateful stream we can hook into by using RxJS as well as an idiomatic api for basic functionality like getting and setting. We can also specify effects to indicate how we want this variable to change over time.

Effects

Noun: a change which is a result or consequence of an action or other cause.
Verb: cause (something) to happen; bring about.

One of this inspirations for this library was an article (that I can no longer find to link to...) that talked about how state management in JS has gotten out of control over the years. After years of doing Redux we've ended up with Stores, Dispatchers, Actions, Selectors, Thunks, Epics, Sagas, Side Effects, and Actors. For StateRx, these concepts are just called "effects".

Effects allow us to specify how we want to change one of our stateful values, and also how we would like to read them through computed changes. If you're coming from Redux, you might have heard them referred to as "actions" and "selectors".

Lets update our example to be a bit more useful and include some effects.

import { createValue } from 'staterx';
import { scan } from 'rxjs/operators';
const counter = createValue({
default: 0,
effects: ({ state$ }) => ({
// here we create two functions that describe how we want to change our value
increment: () => counter.set(val => val + 1),
decrement: () => counter.set(val => val - 1),
// an observable to count of the total number of times our counter has changed
callCount$: state$.pipe(scan(acc => acc + 1, -1))
// an example of an async effect
save: async () => {
const myVal = counter.get();
await fetch('/example/save/', {...}); // do something async
}
})
});
counter.state$.subscribe(val => console.log(val)); // logs 0
counter.increment(); // logs 1
counter.decrement(); // logs 0
// we can also subscribe to our callCount$ effect
counter.callCount$.subscribe(val => console.log(val));

React Example

StateRx ships with a hooks for React so you can directly consume your state in your components. Just import useRx and pass your variable's state$ to the hook. useRx actually works with more than just StateRx, you can pass any RxJS Observable.

import { createValue, useRx } from 'staterx';
  • Count: 0
  • Num Calls: