Skip to content

Instantly share code, notes, and snippets.

@kubk
Last active April 27, 2021 07:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubk/85ca9153afe6285807bb316de4c7a658 to your computer and use it in GitHub Desktop.
Save kubk/85ca9153afe6285807bb316de4c7a658 to your computer and use it in GitHub Desktop.
Counter state using different JS libraries
// RxJS - FRP
const increment = new Subject<void>();
const decrement = new Subject<void>();
const add = new Subject<number>();
type State = number;
const count$ = merge(
increment.pipe(mapTo((state: State) => state + 1))
decrement.pipe(mapTo((state: State) => state - 1)),
add.pipe(map(count => ((state: State) => state + count)))
).pipe(scan((state, reducer) => reducer(state), 0));
const isOdd$ = count$.pipe(
map(count => Boolean(count % 2)),
distinctUntilChanged()
)
// Mobx - OOP
class Store {
state = 0;
constructor() {
makeAutoObservable(this);
}
increment() {
this.state++;
}
decrement() {
this.state++;
}
add(payload: number) {
this.state += payload;
}
get isOdd() {
return Boolean(this.count % 2);
}
}
// Class-free and decorator-free Mobx
function createStore() {
return makeAutoObservable({
state: 0,
increment() {
this.state++;
},
decrement() {
this.state--;
},
add(payload: number) {
this.state += payload;
},
get isOdd() {
return Boolean(this.count % 2);
}
})
}
// RxJS - Stateful
class Store {
private state = new BehaviorSubject(0);
state$ = this.state.asObservable();
isOdd$ = this.state$.pipe(
map(state => Boolean(state.count % 2)),
distinctUntilChanged()
);
increment() {
this.state.next(this.state.value + 1);
}
decrement() {
this.state.next(this.state.value - 1);
}
add(count: number) {
this.state.next(this.state.value + count);
}
}
// Redux recreated using RxJS
const increment = () => ({ type: 'increment' } as const);
const decrement = () => ({ type: 'decrement' } as const);
const add = (count: number) => ({ type: 'decrement', count } as const);
type Action =
| ReturnType<typeof increment>
| ReturnType<typeof decrement>
| ReturnType<typeof add>;
const initialState = 0;
type State = number;
const reducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return state + 1;
case 'decrement':
return state - 1;
case 'add':
return state + action.count;
default:
return state;
}
}
const actions$ = new Subject<Action>();
const state$ = actions$.pipe(
scan<Action, State>((state, action) => reducer(state, action), initialState)
)
const isOdd$ = state$.pipe(
map(count => Boolean(count % 2)),
distinctUntilChanged()
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment