How to make reusable State management
Tags: vue, react, typescript, javascript
Published: 2022-04-19 14:10:50

## 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

> 
1. What are Services in Angular?
2. why Rxjs ?
3. How to Create Service that works in any farmework.
4. How to make state Management using Rxjs.
5. 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.

1. install the following library

```
$ npm install rxjs 
// or
$ yarn add rxjs
```

2. 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.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ls1t8ktkrzb4s4boi3e.png)
 
3. create new `.ts` or `.js` file, I'll name it `counter.ts` (because I'm using typescript here)

```typescript 

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.

1. declar your `initial_state` and `store(BehaviorSubject)`

```typescript 
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;

```

2. the functions:
    1. write a function that returns your Counter `as Observable` so you can subscribe to it, to observe any changes.
    2. write your logic.

```typescript 
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.

```react
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 🔗
https://rxjs.dev/guide/subject#behaviorsubject