Angular 4 Redux ile State Yönetimi 30.12.2017

Herkese merhaba, Angular uygulamamız içerisinde State yönetimini sağlayan redux kütüphanesini anlatacağım, reactjs ile çok kullanılan bu kütüphanenin angular için hazırlanmış olanını projemize dahil edip, konfigürasyonunu yapıp, uygulamamızda kullanabiliriz.

Öncelikle redux orta ve büyük çaplı uygulamalarda kullanıma uygundur, küçük çaplı uygulamalarda redux kullanmamıza gerek yok.

Redux nedir? ne işe yarar? 

Reduxjs uygulamamız içerisinde state (durum) yönetimini sağlayan, yapı olarak bir js objesi (mevcut state'lerin saklandığı) ve custom event oluşturan (event dispatch) bir kütüphanedir. 

Birbiriyle senkronize çalışmasını istediğimiz componentlerin eş zamanlı olarak bazı durumlardan haberdar olmasını ve buna göre davranmasını sağlar.

Nasıl kullanılır?

1.) Öncelikle npm üzerinden kurulumunu yapıyoruz

npm install --save redux ng2-redux

2.) AppModule 'üne import edip konfigürasyonunu yapıyoruz. Konfigürasyonda kullanılan değişkenler:

- ngRdux: redux modülü

- IAppState: redux a tanıtacağımız state şablonu (interface) 

- rootReducer: state yönetimi işlemini yapan , event dispatch ve yeni state döndüren metod

- INITIAL_STATE: state objesinin varsayılan değerleri

import { NgRedux, NgReduxModule} from 'ng2-redux';
export class AppModule {
constructor(ngRedux: NgRedux<IAppState>){
ngRedux.configureStore(rootReducer, INITIAL_STATE);
}
}

3.) Oluşturacağımız state 'lerin, event lerini oluştururken kullanacağımız event isimlerini export eden bir actions dosyasını app dizinine "actions.ts" adında yeni bit ts dosyası olarak oluşturuyoruz.

app/actions.ts

export class AppActions{
readonly INCREMENT = 'INCREMENT';
readonly USER_SET = 'USER_SET';
}

4.) Statelerin oluşturulup , yönetildiği asıl önemli olan dosyayı "store.ts" dosyasını oluşturuyoruz. Buradaki actions event oluşturulması için kullanılır , state ise bu evente bağlı olan state in döndüreceği değerdir. Return kısmındaki "...state" var olan mevcut diğer store objesindeki state'lerin aynı kalmasını sağlar ve bundan sonra store içerisinde istediğimiz state objesini değiştirdiğimiz kısım gelir (counter:state.counter+1 gibi)

import { AppActions } from './actions';

export interface IAppState{
counter: number;

user: {
agency:string;
username:string;
};

}

export const INITIAL_STATE:IAppState = {
counter: 0,

user: {
agency: "",
username: ""
}

};

export function rootReducer(state: IAppState, action): IAppState{
const appActions = new AppActions();

switch (action.type){
case appActions.INCREMENT:
return {
...state,
counter : state.counter + 1

};

case appActions.USER_SET:
return {
...state,
user: action.body
};
}
return state;
}

5.) Compoenent kısmında kullanışı da şu şekildedir;

- Asenkron data kullanımını ve reaktif programlamayı sağlayan "Observable" class'ını, redux'u, state interface'i ve actions'ı component'e dahil ediyoruz.

import { NgRedux, select } from "ng2-redux";
import { IAppState} from '../../store';
import { AppActions } from '../../actions';
import { Observable} from "rxjs/Observable";

- Component'imizde kullanacağımız Observable tipinde değişkenlerimizi oluşturuyoruz

counter$:Observable;
userAgency$:Observable;

- Redux'u ve hangi şablona göre kullanacağımızı constructor metodunda belirtip, Asenkron olarak state 'e bağlayacağımız değişkenlerin değerlerini store içersinde bulup seçerek veriyoruz.

counter$:Observable;
userAgency$:Observable;

constructor(private httpService: HttpService, private ngRedux: NgRedux<IAppState>) {

this.counter$ = ngRedux.select(state => state.counter);
this.userAgency$ = ngRedux.select(state => state.user.agency);
}

- Hangi durumda state oluşturacaksak , yeni bir event dispatch edip , state 'i değiştiriyoruz. Type: actions 'da belirlediğimiz event ismidir, body: state 'e vereceğimiz yeni değerdir.

doLogin($event){
this.params = $event;

this.ngRedux.dispatch({
type: this.appActions.USER_SET,
body: {
agency: "test agency",
username: "Gradar"
}
});
}

increment(){
this.ngRedux.dispatch({
type: this.appActions.INCREMENT
});
}

- Component.html 'de de async pipe 'ı kullanarak state 'e bağlanan değişkeni yazıyoruz;

<h4>{{ userAgency$ | async }}</h4>
<app-loginform [validateForm]="validateForm" (outputLoginForm)="doLogin($event)"></app-loginform>

<p>Counter: {{counter$ | async}}</p>
<button (click)="increment()">Increment</button>

Hepsi bu kadar , sevgiler :)