Dynalon / reactive-state

Redux-clone build with strict typing and RxJS down to its core. Wrist-friendly, no boilerplate or endless switch statements
MIT License
138 stars 7 forks source link
functional-reactive-programming react-redux redux rxjs state-management typescript

Build Status npm version code coverage

Reactive State

A typed, wrist-friendly state container aimed as an alternative to Redux when using RxJS. Written with RxJS in TypeScript but perfectly usable from plain JavaScript. Originally inspired by the blog posting from Michael Zalecki but heavily modified and extended since.

Features

Installation

npm install reactive-state

Documentation

Additionally, there is a small example.ts file and see also see the included unit tests as well.

Example Usage

import { Store } from "reactive-state";
import { Subject } from "rxjs";
import { take } from "rxjs/operators";

// The state for our example app
interface AppState {
    counter: number;
}

const initialState: AppState = { counter: 0 }

const store = Store.create(initialState);

// The .watch() function returns an Observable that emits the selected state change, so we can subscribe to it
store.watch().subscribe(newState => console.log("STATE:", JSON.stringify(newState)));

// the watch() observable always caches the last emitted state, so we will immediately print our inital state:
// [CONSOLE.LOG]: STATE: {"counter":0}

// use a RxJS Subjects as an action
const incrementAction = new Subject<number>();

// A reducer is a function that takes a state and an optional payload, and returns a new state
function incrementReducer(state, payload) {
    return { ...state, counter: state.counter + payload };
};

store.addReducer(incrementAction, incrementReducer);

// lets dispatch some actions

incrementAction.next(1);
// [CONSOLE.LOG]: STATE: {"counter":1}
incrementAction.next(1);
// [CONSOLE.LOG]: STATE: {"counter":2}

// async actions? No problem, no need for a "middleware", just use RxJS
interval(1000).pipe(take(3)).subscribe(() => incrementAction.next(1));
// <PAUSE 1sec>
// [CONSOLE.LOG]: STATE: {"counter":3}
// <PAUSE 1sec>
// [CONSOLE.LOG]: STATE: {"counter":4}
// <PAUSE 1sec>
// [CONSOLE.LOG]: STATE: {"counter":5}

License

MIT.