How to make reusable State management
Mayar Deeb
Posted on April 19, 2022
Code once
If you are a programmer who likes to work with many frameworks or has to, it'll be amazing to use the same code in any framework you use, and without doing any configuration for it, just copy and paste.
- Topics we'll cover
- What are Services in Angular?
- why Rxjs ?
- How to Create Service that works in any farmework.
- How to make state Management using Rxjs.
- How to use Service in React component.
1. What are Services in Angular ?
Services are a great way to share information among classes that don't know each other. by using services you'll be able to:
- fetch data form any component in your app
- use Rxjs operators and others.....
- use it as State management ( what we'll do now)
- and have a clean and beautiful code
2. why Rxjs
RxJS can be used with any frameworks or Pure Javascript without doing any configuration.
RxJS is a library for composing asynchronous and event-based programs by using observable sequences.
RxJS offers a huge collection of operators in mathematical, transformation, filtering, utility, conditional, error handling, join categories that make life easy when used with reactive programming.
3. How to Create Service that work in any farmework.
- install the following library
$ npm install rxjs
// or
$ yarn add rxjs
create a folder to contain all of your services, usually I name it
services
and create it in src/srvices. It doesn't matter where you create it.
create new
.ts
or.js
file, I'll name itcounter.ts
(because I'm using typescript here)
class CounterService {
private static _instance: CounterService;
public static get Instance() {
return this._instance || (this._instance = new this());
}
/////...code here
}
export const _CounterService=CounterService.Instance;
so here we create singleton class because one object should be used to coordinate actions across the system.
4. How to make state Management using Rxjs.
- declar your
initial_state
andstore(BehaviorSubject)
import { BehaviorSubject } from "rxjs";
class CounterService {
private static _instance: CounterService;
public static get Instance() {
return this._instance || (this._instance = new this());
}
private initial_state:number=5;
private Counter = new BehaviorSubject<number>(this.initial_state);
}
export const _CounterService=CounterService.Instance;
- the functions:
- write a function that returns your Counter
as Observable
so you can subscribe to it, to observe any changes. - write your logic.
- write a function that returns your Counter
import { BehaviorSubject, Observable } from "rxjs";
class CounterService {
private static _instance: CounterService;
public static get Instance() {
return this._instance || (this._instance = new this());
}
private initial_state:number=5;
private Counter = new BehaviorSubject<number>(this.initial_state);
//step 1
Counter():Observable<number>{
return this.Counter.asObservable();
}
//step 2
increment():void{
this.Counter.next(this.Counter.getValue()+1);
}
decrement():void{
this.Counter.next(this.Counter.getValue()-1);
}
incrementBy(i:number):void{
this.Counter.next(this.Counter.getValue()+i);
}
}
export const _CounterService=CounterService.Instance;
5. How to use Service in React component.
import { useEffect, useState } from "react";
import { Subscription } from "rxjs";
import { _CounterService } from "src/services/Counter.Service";
const Index = () => {
// create Subscription array to push any Subscription we do
let Subs:Subscription[]=[];
const [counter, setcounter] = useState<number>();
const increment=()=>_CounterService.increment();
const decrement=()=>_CounterService.decrement();
const incrementBy=(i:number)=>_CounterService.incrementBy(i);
useEffect(() => {
//push it to Subs to unsubscribe on component destroy
Subs.push(
_CounterService.Counter()
.subscribe({ next: (res) => counter(res) }));
//to prevent any memory leak
return () =>Subs.forEach(e=>e.unsubscribe())
}, []);
return (
<div>
the Counter is {{counter}}
<button onClick={()=>increment()}>increment</button>
<button onClick={()=>decrement()}>decrement</button>
<button onClick={()=>incrementBy(5)}>increment By 5</button>
</div>
);
};
export default Index;
How it works
The BehaviorSubject
holds one value. When it is subscribed it emits the value immediately and every time this subject gets a new value it emits it too.
note: if you unsubscribe to it you won't get any new values
the end...
you might be wondering 🤔 why Rxjs? why to use this state management and leave Redux or Context or Vuex?
the answer is if you use Rxjs as API service and State management you'll be able to copy this .ts
or .js
file and paste it in any project you have no matter what framework you use.
No configuration is needed. Indeed you'll have great centralized code (your API calls and your State management all in one file)
useful links 🔗
Posted on April 19, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.