{"id":39467,"date":"2026-02-22T04:40:51","date_gmt":"2026-02-22T01:40:51","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=39467"},"modified":"2026-02-22T04:40:51","modified_gmt":"2026-02-22T01:40:51","slug":"angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/","title":{"rendered":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler"},"content":{"rendered":"<p><body><\/p>\n<h2>Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler<\/h2>\n<h3>Giri\u015f<\/h3>\n<p>Modern web uygulamalar\u0131, \u00f6zellikle Angular gibi tek sayfa uygulama (SPA) \u00e7at\u0131lar\u0131nda geli\u015ftirilenler, genellikle karma\u015f\u0131k ve dinamik veri ak\u0131\u015flar\u0131na sahiptir. Kullan\u0131c\u0131 etkile\u015fimleri, sunucu istekleri, bile\u015fenler aras\u0131 ileti\u015fim ve uygulaman\u0131n genel durumu (state) bu karma\u015f\u0131kl\u0131\u011f\u0131n temelini olu\u015fturur. Uygulama b\u00fcy\u00fcd\u00fck\u00e7e, bu durumun y\u00f6netimi giderek zorla\u015f\u0131r ve kontrol d\u0131\u015f\u0131 bir hal alabilir. Durumun nerede depoland\u0131\u011f\u0131, nas\u0131l g\u00fcncellendi\u011fi ve farkl\u0131 bile\u015fenlerin bu duruma nas\u0131l eri\u015fti\u011fi konular\u0131 netle\u015fmedi\u011finde, hatalar ay\u0131klanmas\u0131 g\u00fc\u00e7le\u015fir, uygulaman\u0131n bak\u0131m\u0131 zorla\u015f\u0131r ve \u00f6l\u00e7eklenebilirlik ciddi \u015fekilde etkilenir.<\/p>\n<p>\u0130\u015fte tam bu noktada durum y\u00f6netimi (state management) k\u00fct\u00fcphaneleri devreye girer. Durum y\u00f6netimi, uygulaman\u0131n t\u00fcm verilerini merkezi bir yerde tutarak, bu verilere eri\u015fim ve g\u00fcncelleme s\u00fcre\u00e7lerini tutarl\u0131 ve \u00f6ng\u00f6r\u00fclebilir bir \u015fekilde standartla\u015ft\u0131rmay\u0131 ama\u00e7lar. Angular ekosisteminde NgRx, Akita gibi pop\u00fcler \u00e7\u00f6z\u00fcmler bulunsa da, son y\u0131llarda NGXS, basitli\u011fi, g\u00fc\u00e7l\u00fc TypeScript entegrasyonu ve daha az &#8220;boilerplate&#8221; (tekrarlayan kod) gerektirmesiyle dikkat \u00e7ekmektedir. Bu makalede, Angular uygulamalar\u0131nda NGXS kullanarak durum y\u00f6netiminin nas\u0131l etkili bir \u015fekilde yap\u0131laca\u011f\u0131n\u0131, temel kavramlar\u0131ndan geli\u015fmi\u015f \u00f6zelliklerine kadar detayl\u0131 bir \u015fekilde inceleyece\u011fiz.<\/p>\n<h3>Temel Durum Y\u00f6netimi Kavramlar\u0131<\/h3>\n<p>Durum y\u00f6netimi \u00e7\u00f6z\u00fcmlerinin \u00e7o\u011fu, Redux mimarisinden ilham al\u0131r ve belirli temel kavramlar \u00fczerine kuruludur. NGXS de bu kavramlar\u0131 kendi TypeScript ve RxJS odakl\u0131 yap\u0131s\u0131yla yorumlar:<\/p>\n<p>*   <strong>Durum (State):<\/strong> Uygulaman\u0131n belirli bir andaki t\u00fcm verilerini temsil eden tek, de\u011fi\u015ftirilemez (immutable) bir nesnedir. \u00d6rne\u011fin, bir al\u0131\u015fveri\u015f sepetindeki \u00fcr\u00fcnler, kullan\u0131c\u0131n\u0131n oturum bilgileri veya bir formun mevcut de\u011feri birer durum par\u00e7as\u0131d\u0131r.<br \/>\n*   <strong>Eylem (Action):<\/strong> Durumda bir de\u011fi\u015fiklik yapma niyetini tan\u0131mlayan basit bir mesajd\u0131r. Eylemler, kullan\u0131c\u0131n\u0131n bir butona t\u0131klamas\u0131, sunucudan veri gelmesi veya bir zamanlay\u0131c\u0131n\u0131n sona ermesi gibi olaylar sonucunda tetiklenir. Eylemler genellikle bir <code>type<\/code> \u00f6zelli\u011fine ve duruma etki edecek verileri ta\u015f\u0131yan bir <code>payload<\/code>&#8216;a sahiptir.<br \/>\n*   <strong>Depo (Store):<\/strong> Uygulaman\u0131n t\u00fcm durumunu bar\u0131nd\u0131ran merkezi bir nesnedir. Bile\u015fenler, duruma do\u011frudan eri\u015fmek yerine, depo arac\u0131l\u0131\u011f\u0131yla eylemler g\u00f6nderir ve durumu se\u00e7iciler (selectors) arac\u0131l\u0131\u011f\u0131yla okur.<br \/>\n*   <strong>Se\u00e7ici (Selector):<\/strong> Depodaki durumdan belirli veri par\u00e7alar\u0131n\u0131 ay\u0131klamak ve d\u00f6n\u00fc\u015ft\u00fcrmek i\u00e7in kullan\u0131lan saf (pure) fonksiyonlard\u0131r. Se\u00e7iciler, bile\u015fenlerin yaln\u0131zca ihtiya\u00e7 duyduklar\u0131 verilere eri\u015fmesini sa\u011flar ve durumun yap\u0131s\u0131ndaki de\u011fi\u015fikliklerden etkilenmemelerine yard\u0131mc\u0131 olur.<br \/>\n*   <strong>\u0130\u015fleyici (Handler \/ Reducer):<\/strong> Bir eyleme yan\u0131t olarak mevcut durumu alan ve eylemin y\u00fck\u00fcne (payload) g\u00f6re yeni bir durum d\u00f6nd\u00fcren fonksiyonlard\u0131r. NGXS&#8217;te bu i\u015flev <code>@Action<\/code> dekorat\u00f6r\u00fc ile i\u015faretlenmi\u015f metotlar taraf\u0131ndan yerine getirilir. \u0130\u015fleyiciler, daima mevcut durumu de\u011fi\u015ftirmek yerine, durumun yeni bir kopyas\u0131n\u0131 d\u00f6nd\u00fcrerek de\u011fi\u015ftirilemezlik (immutability) prensibini korumal\u0131d\u0131r.<br \/>\n*   <strong>Yan Etki (Side Effect):<\/strong> Durumda do\u011frudan de\u011fi\u015fiklik yapmayan, ancak eylemler sonucunda tetiklenen asenkron i\u015flemlerdir. API \u00e7a\u011fr\u0131lar\u0131, veritaban\u0131 i\u015flemleri, navigasyon veya zamanlay\u0131c\u0131lar gibi i\u015flemler yan etkilere \u00f6rnek olarak verilebilir. NGXS&#8217;te yan etkiler genellikle <code>@Action<\/code> i\u015fleyicileri i\u00e7inde RxJS operat\u00f6rleri kullan\u0131larak y\u00f6netilir.<\/p>\n<h3>NGXS Nedir? Neden NGXS?<\/h3>\n<p>NGXS (Next Generation eXtendable State management) , Angular uygulamalar\u0131 i\u00e7in RxJS ve TypeScript \u00fczerine in\u015fa edilmi\u015f, Redux ilhaml\u0131 bir durum y\u00f6netim k\u00fct\u00fcphanesidir. Geleneksel Redux yap\u0131lar\u0131n\u0131n aksine, NGXS, dekorat\u00f6rler (decorators) ve s\u0131n\u0131flar (classes) kullanarak daha az &#8220;boilerplate&#8221; kodu ile daha okunabilir ve y\u00f6netilebilir bir kod taban\u0131 sunmay\u0131 hedefler.<\/p>\n<p>NGXS&#8217;i tercih etmek i\u00e7in birka\u00e7 \u00f6nemli neden bulunmaktad\u0131r:<\/p>\n<p>*   <strong>Basit API ve Az Boilerplate:<\/strong> NGXS, Redux&#8217;a k\u0131yasla daha az tekrarlayan kod gerektirir. Dekoratif yap\u0131s\u0131 sayesinde eylemler, durum i\u015fleyicileri ve se\u00e7iciler tek bir <code>State<\/code> s\u0131n\u0131f\u0131 i\u00e7inde tan\u0131mlanabilir, bu da kodu daha derli toplu hale getirir.<br \/>\n*   <strong>TypeScript Odakl\u0131 Tasar\u0131m:<\/strong> NGXS, TypeScript&#8217;in t\u00fcm avantajlar\u0131ndan yararlan\u0131r. T\u00fcr g\u00fcvenli\u011fi, otomatik tamamlama ve derleme zaman\u0131 hatalar\u0131n\u0131n tespiti, b\u00fcy\u00fck projelerde geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131r ve hatalar\u0131 azalt\u0131r.<br \/>\n*   <strong>RxJS Entegrasyonu:<\/strong> NGXS, Angular&#8217;\u0131n reaktif do\u011fas\u0131na m\u00fckemmel uyum sa\u011flayan RxJS ile derinlemesine entegredir. Asenkron i\u015flemlerin ve yan etkilerin y\u00f6netimi, RxJS operat\u00f6rleri ile kolayca yap\u0131labilir.<br \/>\n*   <strong>Performans:<\/strong> De\u011fi\u015ftirilemez durum (immutable state) prensibini benimsemesi ve RxJS&#8217;in g\u00fc\u00e7l\u00fc ak\u0131\u015f y\u00f6netimi sayesinde NGXS, performansl\u0131 bir durum y\u00f6netimi sunar.<br \/>\n*   <strong>Mod\u00fcler Yap\u0131:<\/strong> Uygulaman\u0131n durumunu mant\u0131ksal mod\u00fcllere ay\u0131rarak y\u00f6netme imkan\u0131 sunar. Bu, b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalarda kodun daha d\u00fczenli olmas\u0131n\u0131 sa\u011flar.<br \/>\n*   <strong>Geli\u015ftirici Ara\u00e7lar\u0131 Deste\u011fi:<\/strong> Redux DevTools gibi pop\u00fcler geli\u015ftirici ara\u00e7lar\u0131yla entegrasyon sayesinde, durum de\u011fi\u015fikliklerini izlemek, eylemleri kaydetmek ve hata ay\u0131klamak \u00e7ok daha kolayd\u0131r.<br \/>\n*   <strong>Aktif Topluluk ve Dok\u00fcmantasyon:<\/strong> NGXS, aktif bir geli\u015ftirici toplulu\u011funa ve kapsaml\u0131 dok\u00fcmantasyona sahiptir, bu da \u00f6\u011frenme s\u00fcrecini ve sorun gidermeyi kolayla\u015ft\u0131r\u0131r.<\/p>\n<h3>NGXS Kurulumu ve Temel Kullan\u0131m<\/h3>\n<p>NGXS&#8217;i Angular projenize dahil etmek olduk\u00e7a basittir. \u0130lk ad\u0131m olarak <code>@ngxs\/store<\/code> paketini kurmal\u0131s\u0131n\u0131z:<\/p>\n<pre><code class=\"language-bash\">npm install @ngxs\/store<\/code><\/pre>\n<p>Ard\u0131ndan, <code>app.module.ts<\/code> dosyan\u0131zda <code>NgxsModule<\/code>&#8216;\u00fc import edip uygulaman\u0131z\u0131n k\u00f6k mod\u00fcl\u00fcne kaydetmeniz gerekir:<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.module.ts\nimport { NgModule } from '@angular\/core';\nimport { BrowserModule } from '@angular\/platform-browser';\nimport { NgxsModule } from '@ngxs\/store';\nimport { AppComponent } from '.\/app.component';\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    BrowserModule,\n    NgxsModule.forRoot([]) \/\/ Burada state'lerinizi tan\u0131mlayacaks\u0131n\u0131z\n  ],\n  providers: [],\n  bootstrap: [AppComponent]\n})\nexport class AppModule { }<\/code><\/pre>\n<p>Geli\u015ftirme s\u00fcrecini kolayla\u015ft\u0131rmak i\u00e7in NGXS&#8217;in geli\u015ftirici ara\u00e7lar\u0131 eklentilerini de kurman\u0131z \u00f6nerilir:<\/p>\n<pre><code class=\"language-bash\">npm install @ngxs\/devtools-plugin @ngxs\/logger-plugin<\/code><\/pre>\n<p>Bu eklentileri de <code>NgxsModule.forRoot<\/code> metoduna ekleyerek etkinle\u015ftirebilirsiniz:<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.module.ts\nimport { NgxsModule } from '@ngxs\/store';\nimport { NgxsReduxDevtoolsPluginModule } from '@ngxs\/devtools-plugin';\nimport { NgxsLoggerPluginModule } from '@ngxs\/logger-plugin';\n\n@NgModule({\n  imports: [\n    \/\/ ...\n    NgxsModule.forRoot([], { developmentMode: !environment.production }),\n    NgxsReduxDevtoolsPluginModule.forRoot({\n      disabled: environment.production\n    }),\n    NgxsLoggerPluginModule.forRoot({\n      disabled: environment.production\n    })\n  ],\n  \/\/ ...\n})\nexport class AppModule { }<\/code><\/pre>\n<p><code>developmentMode<\/code> ayar\u0131 ve eklentilerin <code>disabled<\/code> \u00f6zelli\u011fi, \u00fcretim ortam\u0131nda bu ara\u00e7lar\u0131n devre d\u0131\u015f\u0131 b\u0131rak\u0131lmas\u0131n\u0131 sa\u011flar, bu da performans ve g\u00fcvenlik a\u00e7\u0131s\u0131ndan \u00f6nemlidir.<\/p>\n<h3>Bir NGXS State Tan\u0131mlamak<\/h3>\n<p>NGXS&#8217;te durum (state), bir TypeScript s\u0131n\u0131f\u0131 olarak tan\u0131mlan\u0131r ve <code>@State<\/code> dekorat\u00f6r\u00fc ile i\u015faretlenir. Bu s\u0131n\u0131f, durumun varsay\u0131lan de\u011ferlerini (defaults) ve eylem i\u015fleyicilerini (action handlers) i\u00e7erir.<\/p>\n<p>\u00d6rnek olarak, bir <code>Todo<\/code> uygulamas\u0131n\u0131n durumunu y\u00f6netmek i\u00e7in bir <code>TodoState<\/code> tan\u0131mlayal\u0131m:<\/p>\n<pre><code class=\"language-typescript\">\/\/ models\/todo.model.ts\nexport interface Todo {\n  id: string;\n  title: string;\n  completed: boolean;\n}\n\n\/\/ state\/todo.state.ts\nimport { State, Action, StateContext, Selector } from '@ngxs\/store';\nimport { Todo } from '..\/models\/todo.model';\n\n\/\/ State'in yap\u0131s\u0131n\u0131 tan\u0131mlayan aray\u00fcz\nexport interface TodoStateModel {\n  todos: Todo[];\n}\n\n@State<TodoStateModel>({\n  name: 'todo', \/\/ State'in benzersiz ad\u0131\n  defaults: {\n    todos: [] \/\/ State'in ba\u015flang\u0131\u00e7\/varsay\u0131lan de\u011feri\n  }\n})\nexport class TodoState {\n  \/\/ Eylem i\u015fleyicileri ve se\u00e7iciler buraya gelecek\n}<\/code><\/pre>\n<p><code>@State<\/code> dekorat\u00f6r\u00fc iki ana \u00f6zellik al\u0131r:<br \/>\n*   <code>name<\/code>: Durumun global olarak eri\u015filece\u011fi benzersiz ad\u0131d\u0131r.<br \/>\n*   <code>defaults<\/code>: Durumun ba\u015flang\u0131\u00e7ta alaca\u011f\u0131 varsay\u0131lan de\u011ferlerdir.<\/p>\n<h3>Eylemler (Actions) Olu\u015fturma<\/h3>\n<p>Eylemler, duruma ne t\u00fcr bir de\u011fi\u015fiklik yap\u0131laca\u011f\u0131n\u0131 bildiren mesajlard\u0131r. NGXS&#8217;te eylemler, <code>static readonly type<\/code> \u00f6zelli\u011fine sahip basit TypeScript s\u0131n\u0131flar\u0131 olarak tan\u0131mlan\u0131r. Bu <code>type<\/code> \u00f6zelli\u011fi, eylemin benzersiz tan\u0131mlay\u0131c\u0131s\u0131d\u0131r. Eylemin ta\u015f\u0131mas\u0131 gereken veriler (payload), constructor \u00fczerinden iletilir.<\/p>\n<pre><code class=\"language-typescript\">\/\/ state\/todo.actions.ts\nimport { Todo } from '..\/models\/todo.model';\n\nexport class AddTodo {\n  static readonly type = '[Todo] Add Todo'; \/\/ Eylemin benzersiz tipi\n  constructor(public payload: Todo) {} \/\/ Eylemin ta\u015f\u0131d\u0131\u011f\u0131 veri\n}\n\nexport class RemoveTodo {\n  static readonly type = '[Todo] Remove Todo';\n  constructor(public id: string) {}\n}\n\nexport class ToggleTodo {\n  static readonly type = '[Todo] Toggle Todo';\n  constructor(public id: string) {}\n}\n\nexport class LoadTodos {\n  static readonly type = '[Todo] Load Todos';\n}\n\nexport class SetTodos {\n  static readonly type = '[Todo] Set Todos';\n  constructor(public payload: Todo[]) {}\n}<\/code><\/pre>\n<p>Bu eylem s\u0131n\u0131flar\u0131, uygulaman\u0131zda <code>Store<\/code> servisi arac\u0131l\u0131\u011f\u0131yla g\u00f6nderilecektir.<\/p>\n<h3>Eylemleri \u0130\u015fleme (Action Handling)<\/h3>\n<p>Eylemler, <code>State<\/code> s\u0131n\u0131f\u0131 i\u00e7indeki metotlar taraf\u0131ndan <code>@Action<\/code> dekorat\u00f6r\u00fc kullan\u0131larak i\u015flenir. Bu metotlar, <code>StateContext<\/code> (k\u0131saca <code>ctx<\/code>) nesnesini ve eylemin kendisini parametre olarak al\u0131r. <code>StateContext<\/code>, mevcut duruma eri\u015fim (<code>getState()<\/code>), durumu g\u00fcncelleme (<code>setState()<\/code>, <code>patchState()<\/code>) ve di\u011fer eylemleri g\u00f6nderme (<code>dispatch()<\/code>) gibi y\u00f6ntemler sa\u011flar.<\/p>\n<p>Durum g\u00fcncellenirken, de\u011fi\u015ftirilemezlik (immutability) prensibine kesinlikle uyulmal\u0131d\u0131r. Yani, mevcut durumu do\u011frudan de\u011fi\u015ftirmek yerine, durumun yeni bir kopyas\u0131 olu\u015fturulmal\u0131 ve bu kopya \u00fczerinde de\u011fi\u015fiklikler yap\u0131lmal\u0131d\u0131r. NGXS&#8217;in <code>setState<\/code> ve <code>patchState<\/code> metotlar\u0131 bu s\u00fcreci kolayla\u015ft\u0131r\u0131r.<\/p>\n<p><code>setState()<\/code>: Durumun tamam\u0131n\u0131 yeni bir nesne ile de\u011fi\u015ftirir.<br \/>\n<code>patchState()<\/code>: Durumun yaln\u0131zca belirli bir b\u00f6l\u00fcm\u00fcn\u00fc g\u00fcnceller (derin bir birle\u015ftirme yapar).<\/p>\n<p><code>TodoState<\/code> s\u0131n\u0131f\u0131m\u0131za eylem i\u015fleyicilerini ekleyelim:<\/p>\n<pre><code class=\"language-typescript\">\/\/ state\/todo.state.ts\nimport { State, Action, StateContext, Selector } from '@ngxs\/store';\nimport { Todo } from '..\/models\/todo.model';\nimport { AddTodo, RemoveTodo, ToggleTodo, SetTodos } from '.\/todo.actions';\nimport { v4 as uuidv4 } from 'uuid'; \/\/ Benzersiz ID'ler i\u00e7in\n\nexport interface TodoStateModel {\n  todos: Todo[];\n}\n\n@State<TodoStateModel>({\n  name: 'todo',\n  defaults: {\n    todos: []\n  }\n})\nexport class TodoState {\n\n  @Action(AddTodo)\n  addTodo(ctx: StateContext<TodoStateModel>, action: AddTodo) {\n    const state = ctx.getState();\n    const newTodo = { ...action.payload, id: uuidv4(), completed: false };\n    ctx.setState({\n      ...state,\n      todos: [...state.todos, newTodo]\n    });\n  }\n\n  @Action(RemoveTodo)\n  removeTodo(ctx: StateContext<TodoStateModel>, action: RemoveTodo) {\n    const state = ctx.getState();\n    ctx.patchState({\n      todos: state.todos.filter(todo => todo.id !== action.id)\n    });\n  }\n\n  @Action(ToggleTodo)\n  toggleTodo(ctx: StateContext<TodoStateModel>, action: ToggleTodo) {\n    const state = ctx.getState();\n    ctx.patchState({\n      todos: state.todos.map(todo =>\n        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo\n      )\n    });\n  }\n\n  @Action(SetTodos)\n  setTodos(ctx: StateContext<TodoStateModel>, action: SetTodos) {\n    ctx.patchState({\n      todos: action.payload\n    });\n  }\n}<\/code><\/pre>\n<p>Yukar\u0131daki \u00f6rnekte, <code>addTodo<\/code> metodunda <code>setState<\/code> kullanarak t\u00fcm durumu g\u00fcncellerken, <code>removeTodo<\/code> ve <code>toggleTodo<\/code> metotlar\u0131nda <code>patchState<\/code> kullanarak sadece <code>todos<\/code> dizisini g\u00fcncelledik. <code>patchState<\/code> genellikle daha kullan\u0131\u015fl\u0131d\u0131r \u00e7\u00fcnk\u00fc durumun di\u011fer k\u0131s\u0131mlar\u0131n\u0131 manuel olarak kopyalamak zorunda kalmazs\u0131n\u0131z.<\/p>\n<p>Bu <code>TodoState<\/code> s\u0131n\u0131f\u0131n\u0131 <code>app.module.ts<\/code>&#8216;deki <code>NgxsModule.forRoot<\/code> metoduna eklemeyi unutmay\u0131n:<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.module.ts\nimport { NgxsModule } from '@ngxs\/store';\nimport { TodoState } from '.\/state\/todo.state'; \/\/ State s\u0131n\u0131f\u0131n\u0131 import edin\n\n@NgModule({\n  imports: [\n    \/\/ ...\n    NgxsModule.forRoot([TodoState], { developmentMode: !environment.production }), \/\/ State'i buraya ekleyin\n    \/\/ ...\n  ],\n  \/\/ ...\n})\nexport class AppModule { }<\/code><\/pre>\n<h3>Verileri Se\u00e7icilerle (Selectors) Okuma<\/h3>\n<p>Se\u00e7iciler, durumdan veri okumak i\u00e7in kullan\u0131lan saf fonksiyonlard\u0131r. Bile\u015fenlerin do\u011frudan duruma eri\u015fmesini engeller ve durumun yap\u0131s\u0131ndaki de\u011fi\u015fikliklerin bile\u015fenleri etkilemesini \u00f6nler. NGXS&#8217;te se\u00e7iciler, <code>@Selector<\/code> dekorat\u00f6r\u00fc ile i\u015faretlenmi\u015f <code>static<\/code> metotlar olarak tan\u0131mlan\u0131r.<\/p>\n<pre><code class=\"language-typescript\">\/\/ state\/todo.state.ts\nimport { State, Action, StateContext, Selector } from '@ngxs\/store';\n\/\/ ... di\u011fer importlar\n\n@State<TodoStateModel>({\n  name: 'todo',\n  defaults: {\n    todos: []\n  }\n})\nexport class TodoState {\n  \/\/ ... eylem i\u015fleyicileri\n\n  @Selector()\n  static getAllTodos(state: TodoStateModel) {\n    return state.todos;\n  }\n\n  @Selector()\n  static getCompletedTodos(state: TodoStateModel) {\n    return state.todos.filter(todo => todo.completed);\n  }\n\n  @Selector()\n  static getActiveTodos(state: TodoStateModel) {\n    return state.todos.filter(todo => !todo.completed);\n  }\n\n  \/\/ Parametreli se\u00e7ici \u00f6rne\u011fi\n  static getTodoById(id: string) {\n    return createSelector([TodoState], (state: TodoStateModel) => {\n      return state.todos.find(todo => todo.id === id);\n    });\n  }\n}<\/code><\/pre>\n<p>Bile\u015fenlerde bu se\u00e7icileri kullanmak i\u00e7in <code>Store<\/code> servisini enjekte etmeli ve <code>select()<\/code> veya <code>selectSnapshot()<\/code> metotlar\u0131n\u0131 kullanmal\u0131s\u0131n\u0131z:<\/p>\n<pre><code class=\"language-typescript\">\/\/ components\/todo-list\/todo-list.component.ts\nimport { Component, OnInit } from '@angular\/core';\nimport { Store, Select } from '@ngxs\/store';\nimport { Observable } from 'rxjs';\nimport { Todo } from '..\/..\/models\/todo.model';\nimport { AddTodo, RemoveTodo, ToggleTodo } from '..\/..\/state\/todo.actions';\nimport { TodoState } from '..\/..\/state\/todo.state';\n\n@Component({\n  selector: 'app-todo-list',\n  templateUrl: '.\/todo-list.component.html',\n  styleUrls: ['.\/todo-list.component.css']\n})\nexport class TodoListComponent implements OnInit {\n\n  @Select(TodoState.getAllTodos) todos$!: Observable<Todo[]>;\n  @Select(TodoState.getCompletedTodos) completedTodos$!: Observable<Todo[]>;\n\n  constructor(private store: Store) { }\n\n  ngOnInit(): void {\n    \/\/ Durumdan anl\u0131k veri almak i\u00e7in selectSnapshot()\n    const allTodosSnapshot = this.store.selectSnapshot(TodoState.getAllTodos);\n    console.log('Anl\u0131k t\u00fcm todolar:', allTodosSnapshot);\n  }\n\n  addTodo(title: string) {\n    const newTodo: Todo = { id: '', title, completed: false }; \/\/ ID state i\u00e7inde atanacak\n    this.store.dispatch(new AddTodo(newTodo));\n  }\n\n  removeTodo(id: string) {\n    this.store.dispatch(new RemoveTodo(id));\n  }\n\n  toggleTodo(id: string) {\n    this.store.dispatch(new ToggleTodo(id));\n  }\n\n  getTodoDetails(id: string) {\n    \/\/ Parametreli se\u00e7iciyi kullanma\n    this.store.select(TodoState.getTodoById(id)).subscribe(todo => {\n      console.log(<code>Todo ${id} detaylar\u0131:<\/code>, todo);\n    });\n  }\n}<\/code><\/pre>\n<p><code>@Select<\/code> dekorat\u00f6r\u00fc, bir se\u00e7iciyi do\u011frudan bir <code>Observable<\/code>&#8216;a ba\u011flayarak bile\u015fenlerde veri ak\u0131\u015f\u0131n\u0131 kolayla\u015ft\u0131r\u0131r. <code>selectSnapshot()<\/code> ise o anki durumun tek seferlik bir kopyas\u0131n\u0131 alman\u0131z\u0131 sa\u011flar.<\/p>\n<h3>Asenkron \u0130\u015flemler ve Yan Etkiler<\/h3>\n<p>Ger\u00e7ek d\u00fcnya uygulamalar\u0131nda, durum de\u011fi\u015fiklikleri genellikle asenkron i\u015flemler (API \u00e7a\u011fr\u0131lar\u0131, zamanlay\u0131c\u0131lar vb.) i\u00e7erir. NGXS&#8217;te bu yan etkiler, <code>@Action<\/code> i\u015fleyicileri i\u00e7inde RxJS operat\u00f6rleri kullan\u0131larak y\u00f6netilir. Genellikle bir eylem tetiklenir, bu eylem bir API \u00e7a\u011fr\u0131s\u0131n\u0131 ba\u015flat\u0131r ve API&#8217;den gelen yan\u0131ta g\u00f6re ba\u015fka bir eylem (\u00f6rne\u011fin, ba\u015far\u0131l\u0131 veya ba\u015far\u0131s\u0131z bir eylem) g\u00f6nderilerek durum g\u00fcncellenir.<\/p>\n<p>\u00d6rnek olarak, bir API&#8217;den todo listesi y\u00fckleyelim:<\/p>\n<pre><code class=\"language-typescript\">\/\/ services\/todo.service.ts\nimport { Injectable } from '@angular\/core';\nimport { HttpClient } from '@angular\/common\/http';\nimport { Observable, of } from 'rxjs';\nimport { Todo } from '..\/models\/todo.model';\n\n@Injectable({ providedIn: 'root' })\nexport class TodoService {\n  private apiUrl = 'https:\/\/jsonplaceholder.typicode.com\/todos'; \/\/ \u00d6rnek API\n\n  constructor(private http: HttpClient) {}\n\n  getTodos(): Observable<Todo[]> {\n    \/\/ Ger\u00e7ek bir API \u00e7a\u011fr\u0131s\u0131\n    return this.http.get<Todo[]>(this.apiUrl);\n    \/\/ Veya sim\u00fcle edilmi\u015f bir \u00e7a\u011fr\u0131\n    \/\/ return of([\n    \/\/   { id: '1', title: 'Learn NGXS', completed: false },\n    \/\/   { id: '2', title: 'Build an app', completed: true }\n    \/\/ ]);\n  }\n}\n\n\/\/ state\/todo.state.ts\nimport { State, Action, StateContext, Selector } from '@ngxs\/store';\nimport { Todo } from '..\/models\/todo.model';\nimport { AddTodo, RemoveTodo, ToggleTodo, LoadTodos, SetTodos } from '.\/todo.actions';\nimport { TodoService } from '..\/services\/todo.service';\nimport { tap, catchError } from 'rxjs\/operators';\nimport { Injectable } from '@angular\/core';\nimport { throwError } from 'rxjs';\n\nexport interface TodoStateModel {\n  todos: Todo[];\n  loading: boolean; \/\/ Y\u00fckleme durumu\n  error: string | null; \/\/ Hata mesaj\u0131\n}\n\n@Injectable() \/\/ Servis enjeksiyonu i\u00e7in gerekli\n@State<TodoStateModel>({\n  name: 'todo',\n  defaults: {\n    todos: [],\n    loading: false,\n    error: null\n  }\n})\nexport class TodoState {\n  constructor(private todoService: TodoService) {} \/\/ Servisi enjekte et\n\n  \/\/ ... di\u011fer eylem i\u015fleyicileri\n\n  @Action(LoadTodos)\n  loadTodos(ctx: StateContext<TodoStateModel>) {\n    ctx.patchState({ loading: true, error: null }); \/\/ Y\u00fckleme ba\u015flad\u0131\n\n    return this.todoService.getTodos().pipe(\n      tap(todos => {\n        \/\/ API'den gelen verilerle durumu g\u00fcncellemek i\u00e7in ba\u015fka bir eylem g\u00f6nder\n        ctx.dispatch(new SetTodos(todos));\n        ctx.patchState({ loading: false }); \/\/ Y\u00fckleme bitti\n      }),\n      catchError(error => {\n        ctx.patchState({\n          loading: false,\n          error: 'Failed to load todos.' \/\/ Hata mesaj\u0131n\u0131 kaydet\n        });\n        return throwError(() => new Error('Failed to load todos')); \/\/ Hata ak\u0131\u015f\u0131n\u0131 devam ettir\n      })\n    );\n  }\n\n  @Selector()\n  static isLoading(state: TodoStateModel) {\n    return state.loading;\n  }\n\n  @Selector()\n  static getError(state: TodoStateModel) {\n    return state.error;\n  }\n}<\/code><\/pre>\n<p><code>loadTodos<\/code> eyleminde, <code>TodoService<\/code>&#8216;den veri \u00e7ekilir. <code>tap<\/code> operat\u00f6r\u00fc, API yan\u0131t\u0131n\u0131 ald\u0131ktan sonra <code>SetTodos<\/code> eylemini g\u00f6nderir ve y\u00fckleme durumunu g\u00fcnceller. <code>catchError<\/code> operat\u00f6r\u00fc ise herhangi bir hata durumunda durumu g\u00fcncelleyerek kullan\u0131c\u0131ya bilgi verilmesini sa\u011flar. <code>TodoState<\/code> s\u0131n\u0131f\u0131na <code>@Injectable()<\/code> dekorat\u00f6r\u00fcn\u00fc eklemeyi ve <code>AppModule<\/code>&#8216;deki <code>providers<\/code> dizisine <code>TodoService<\/code>&#8216;i eklemeyi unutmay\u0131n.<\/p>\n<h3>NGXS Pluginleri<\/h3>\n<p>NGXS, \u00e7ekirdek i\u015flevselli\u011finin yan\u0131 s\u0131ra, geli\u015ftirme ve \u00fcretim ortamlar\u0131nda faydal\u0131 olabilecek bir dizi eklenti (plugin) sunar:<\/p>\n<p>*   <strong><code>@ngxs\/devtools-plugin<\/code>:<\/strong> Redux DevTools uzant\u0131s\u0131 ile entegrasyon sa\u011flar. Bu, durum de\u011fi\u015fikliklerini, eylem ge\u00e7mi\u015fini ve zaman yolculu\u011fu hata ay\u0131klamas\u0131n\u0131 m\u00fcmk\u00fcn k\u0131lar.<br \/>\n*   <strong><code>@ngxs\/logger-plugin<\/code>:<\/strong> Konsola her eylemi ve durum de\u011fi\u015fikli\u011fini loglar. Geli\u015ftirme s\u0131ras\u0131nda durumu ve eylem ak\u0131\u015f\u0131n\u0131 anlamak i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<br \/>\n*   <strong><code>@ngxs\/storage-plugin<\/code>:<\/strong> Durumu <code>localStorage<\/code> veya <code>sessionStorage<\/code> gibi taray\u0131c\u0131 depolama alanlar\u0131nda kal\u0131c\u0131 hale getirir. Bu sayede sayfa yenilendi\u011finde bile durum korunabilir.<br \/>\n*   <strong><code>@ngxs\/form-plugin<\/code>:<\/strong> Angular formlar\u0131 ile NGXS durumunu senkronize etmeyi kolayla\u015ft\u0131r\u0131r.<br \/>\n*   <strong><code>@ngxs\/websocket-plugin<\/code>:<\/strong> WebSocket olaylar\u0131n\u0131 NGXS eylemlerine ba\u011flamak i\u00e7in kullan\u0131l\u0131r.<\/p>\n<p>Bu eklentilerin kurulumu ve kullan\u0131m\u0131, <code>NgxsModule.forRoot<\/code> metoduna eklenmeleriyle ger\u00e7ekle\u015ftirilir, t\u0131pk\u0131 <code>devtools<\/code> ve <code>logger<\/code> \u00f6rneklerinde oldu\u011fu gibi.<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.module.ts\nimport { NgxsStoragePluginModule } from '@ngxs\/storage-plugin';\n\n@NgModule({\n  imports: [\n    \/\/ ...\n    NgxsModule.forRoot([TodoState], { developmentMode: !environment.production }),\n    NgxsReduxDevtoolsPluginModule.forRoot({ disabled: environment.production }),\n    NgxsLoggerPluginModule.forRoot({ disabled: environment.production }),\n    NgxsStoragePluginModule.forRoot({\n      key: ['todo.todos'] \/\/ Hangi state'lerin depolanaca\u011f\u0131n\u0131 belirtin\n    })\n  ],\n  \/\/ ...\n})\nexport class AppModule { }<\/code><\/pre>\n<p>Yukar\u0131daki \u00f6rnekte <code>key<\/code> \u00f6zelli\u011fi, <code>todo<\/code> state&#8217;i i\u00e7indeki sadece <code>todos<\/code> b\u00f6l\u00fcm\u00fcn\u00fcn kal\u0131c\u0131 hale getirilece\u011fini belirtir.<\/p>\n<h3>Geli\u015fmi\u015f Konular<\/h3>\n<h4>Mod\u00fcler Yap\u0131 ve Feature State&#8217;ler<\/h4>\n<p>B\u00fcy\u00fck uygulamalarda, t\u00fcm state&#8217;leri tek bir <code>NgxsModule.forRoot<\/code> i\u00e7inde tutmak yerine, bunlar\u0131 mant\u0131ksal mod\u00fcllere ay\u0131rmak daha iyi bir yakla\u015f\u0131md\u0131r. NGXS, <code>NgxsModule.forFeature<\/code> metodu ile bunu destekler. Bu, her Angular mod\u00fcl\u00fcn\u00fcn kendi ilgili state&#8217;lerini tan\u0131mlamas\u0131na olanak tan\u0131r.<\/p>\n<pre><code class=\"language-typescript\">\/\/ user.module.ts\nimport { NgModule } from '@angular\/core';\nimport { CommonModule } from '@angular\/common';\nimport { NgxsModule } from '@ngxs\/store';\nimport { UserState } from '.\/state\/user.state'; \/\/ User state'ini import edin\n\n@NgModule({\n  imports: [\n    CommonModule,\n    NgxsModule.forFeature([UserState]) \/\/ Feature state'i burada kaydet\n  ],\n  declarations: []\n})\nexport class UserModule { }<\/code><\/pre>\n<p>Bu sayede, sadece ilgili mod\u00fcl y\u00fcklendi\u011finde (<code>lazy loading<\/code> ile) o mod\u00fcl\u00fcn state&#8217;leri de y\u00fcklenir, bu da ba\u015flang\u0131\u00e7 performans\u0131n\u0131 art\u0131r\u0131r ve kodun daha d\u00fczenli olmas\u0131n\u0131 sa\u011flar.<\/p>\n<h4>State Birle\u015ftirme (State Composition)<\/h4>\n<p>NGXS, <code>@Selector<\/code> dekorat\u00f6r\u00fcn\u00fc kullanarak birden fazla state&#8217;ten veri birle\u015ftiren veya d\u00f6n\u00fc\u015ft\u00fcren se\u00e7iciler olu\u015fturmay\u0131 destekler. Bu, karma\u015f\u0131k veri g\u00f6r\u00fcn\u00fcmleri olu\u015fturmak i\u00e7in g\u00fc\u00e7l\u00fc bir mekanizmad\u0131r.<\/p>\n<pre><code class=\"language-typescript\">\/\/ state\/app.state.ts (veya ba\u015fka bir state)\nimport { State, Selector } from '@ngxs\/store';\nimport { TodoState, TodoStateModel } from '.\/todo.state';\nimport { UserState, UserStateModel } from '.\/user.state';\n\n@State({\n  name: 'app',\n  defaults: {}\n})\nexport class AppState {\n\n  @Selector([TodoState, UserState])\n  static getDashboardData(todoState: TodoStateModel, userState: UserStateModel) {\n    \/\/ Her iki state'ten verileri al\u0131p birle\u015ftirme\n    const totalTodos = todoState.todos.length;\n    const completedTodos = todoState.todos.filter(todo => todo.completed).length;\n    const userName = userState.user?.name || 'Guest';\n\n    return {\n      userName,\n      totalTodos,\n      completedTodos,\n      pendingTodos: totalTodos - completedTodos\n    };\n  }\n}<\/code><\/pre>\n<p>Bu se\u00e7ici, <code>TodoState<\/code> ve <code>UserState<\/code>&#8216;ten gelen verileri alarak bir dashboard i\u00e7in \u00f6zet bir g\u00f6r\u00fcn\u00fcm olu\u015fturur.<\/p>\n<h4>Hata Y\u00f6netimi<\/h4>\n<p>Asenkron i\u015flemlerde hata y\u00f6netimi kritik \u00f6neme sahiptir. NGXS&#8217;te, <code>@Action<\/code> i\u015fleyicileri i\u00e7inde RxJS&#8217;in <code>catchError<\/code> operat\u00f6r\u00fc kullan\u0131larak hatalar yakalanabilir ve duruma kaydedilebilir. Bu, UI&#8217;da kullan\u0131c\u0131ya hata mesajlar\u0131 g\u00f6stermek veya hata durumuna g\u00f6re farkl\u0131 eylemler tetiklemek i\u00e7in kullan\u0131labilir.<\/p>\n<pre><code class=\"language-typescript\">\/\/ ... TodoState i\u00e7indeki loadTodos metodundan \u00f6rnek\n@Action(LoadTodos)\nloadTodos(ctx: StateContext<TodoStateModel>) {\n  ctx.patchState({ loading: true, error: null });\n\n  return this.todoService.getTodos().pipe(\n    tap(todos => {\n      ctx.dispatch(new SetTodos(todos));\n      ctx.patchState({ loading: false });\n    }),\n    catchError(error => {\n      console.error('API Error:', error);\n      ctx.patchState({\n        loading: false,\n        error: 'Todo listesi y\u00fcklenirken bir hata olu\u015ftu.'\n      });\n      return throwError(() => new Error('API \u00e7a\u011fr\u0131s\u0131 ba\u015far\u0131s\u0131z oldu')); \/\/ Hata ak\u0131\u015f\u0131n\u0131 devam ettir\n    })\n  );\n}<\/code><\/pre>\n<h4>Test Edilebilirlik<\/h4>\n<p>NGXS, durum y\u00f6netim kodunuzun kolayca test edilebilir olmas\u0131n\u0131 sa\u011flar. State s\u0131n\u0131flar\u0131, servisler ve eylemler ba\u011f\u0131ms\u0131z birimler olarak test edilebilir. <code>@ngxs\/store\/testing<\/code> mod\u00fcl\u00fc, test ortam\u0131nda NGXS store&#8217;unu mock&#8217;lamak ve test senaryolar\u0131n\u0131 yazmak i\u00e7in yard\u0131mc\u0131 ara\u00e7lar sunar.<\/p>\n<pre><code class=\"language-typescript\">\/\/ state\/todo.state.spec.ts (\u00d6rnek Jest testi)\nimport { TestBed } from '@angular\/core\/testing';\nimport { NgxsModule, Store } from '@ngxs\/store';\nimport { TodoState, TodoStateModel } from '.\/todo.state';\nimport { AddTodo, RemoveTodo, ToggleTodo } from '.\/todo.actions';\nimport { Todo } from '..\/models\/todo.model';\n\ndescribe('TodoState', () => {\n  let store: Store;\n\n  beforeEach(() => {\n    TestBed.configureTestingModule({\n      imports: [NgxsModule.forRoot([TodoState])]\n    });\n    store = TestBed.inject(Store);\n  });\n\n  it('should have a default state', () => {\n    const todos = store.selectSnapshot(TodoState.getAllTodos);\n    expect(todos).toEqual([]);\n  });\n\n  it('should add a todo', () => {\n    const newTodo: Todo = { id: '', title: 'Test Todo', completed: false };\n    store.dispatch(new AddTodo(newTodo));\n    const todos = store.selectSnapshot(TodoState.getAllTodos);\n    expect(todos.length).toBe(1);\n    expect(todos[0].title).toBe('Test Todo');\n  });\n\n  it('should remove a todo', () => {\n    const todo1: Todo = { id: '1', title: 'Test Todo 1', completed: false };\n    const todo2: Todo = { id: '2', title: 'Test Todo 2', completed: false };\n    store.dispatch(new AddTodo(todo1));\n    store.dispatch(new AddTodo(todo2));\n\n    store.dispatch(new RemoveTodo('1'));\n    const todos = store.selectSnapshot(TodoState.getAllTodos);\n    expect(todos.length).toBe(1);\n    expect(todos[0].id).toBe('2');\n  });\n\n  \/\/ Di\u011fer action ve selector testleri...\n});<\/code><\/pre>\n<h3>NGXS&#8217;in Avantajlar\u0131 ve Dezavantajlar\u0131<\/h3>\n<p>Her ara\u00e7 gibi NGXS&#8217;in de kendine \u00f6zg\u00fc avantajlar\u0131 ve dezavantajlar\u0131 vard\u0131r:<\/p>\n<p><strong>Avantajlar\u0131:<\/strong><br \/>\n*   <strong>Az Boilerplate:<\/strong> Redux tabanl\u0131 di\u011fer \u00e7\u00f6z\u00fcmlere g\u00f6re daha az tekrarlayan kod gerektirir, bu da geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131r\u0131r.<br \/>\n*   <strong>TypeScript Deste\u011fi:<\/strong> G\u00fc\u00e7l\u00fc TypeScript entegrasyonu sayesinde t\u00fcr g\u00fcvenli\u011fi ve daha iyi geli\u015ftirici deneyimi sunar.<br \/>\n*   <strong>Dekorat\u00f6r Tabanl\u0131 API:<\/strong> <code>@State<\/code>, <code>@Action<\/code>, <code>@Selector<\/code> gibi dekorat\u00f6rler, kodu daha okunabilir ve y\u00f6netilebilir hale getirir.<br \/>\n*   <strong>RxJS Entegrasyonu:<\/strong> Angular&#8217;\u0131n reaktif do\u011fas\u0131na uyumlu, asenkron i\u015flemleri ve veri ak\u0131\u015flar\u0131n\u0131 kolayca y\u00f6netir.<br \/>\n*   <strong>Mod\u00fcler Yap\u0131:<\/strong> <code>forFeature<\/code> \u00f6zelli\u011fi ile b\u00fcy\u00fck uygulamalarda state&#8217;leri mod\u00fcllere ay\u0131rma imkan\u0131 sunar.<br \/>\n*   <strong>Geli\u015ftirici Ara\u00e7lar\u0131:<\/strong> Redux DevTools ve logger eklentileri sayesinde hata ay\u0131klama ve durum izleme kolayla\u015f\u0131r.<br \/>\n*   <strong>Performans:<\/strong> Immutable state prensibi ve RxJS&#8217;in verimli kullan\u0131m\u0131 ile performansl\u0131 \u00e7al\u0131\u015f\u0131r.<\/p>\n<p><strong>Dezavantajlar\u0131:<\/strong><br \/>\n*   <strong>RxJS Bilgisi Gereklili\u011fi:<\/strong> RxJS&#8217;e a\u015fina olmayan geli\u015ftiriciler i\u00e7in \u00f6\u011frenme e\u011frisi olabilir.<br \/>\n*   <strong>Yeni \u00d6\u011frenme E\u011frisi:<\/strong> Redux veya NgRx gibi daha k\u00f6kl\u00fc \u00e7\u00f6z\u00fcmlere al\u0131\u015fk\u0131n geli\u015ftiriciler i\u00e7in farkl\u0131 bir API&#8217;ye adapte olma s\u00fcreci gerektirebilir.<br \/>\n*   <strong>NgRx Kadar Olgun De\u011fil:<\/strong> NgRx kadar uzun bir ge\u00e7mi\u015fe ve geni\u015f bir ekosisteme sahip de\u011fildir, ancak h\u0131zla geli\u015fmektedir.<br \/>\n*   <strong>\u00c7ok Fazla State S\u0131n\u0131f\u0131:<\/strong> \u00c7ok b\u00fcy\u00fck projelerde, her bir \u00f6zellik i\u00e7in ayr\u0131 bir <code>State<\/code> s\u0131n\u0131f\u0131 olu\u015fturmak, dosya say\u0131s\u0131n\u0131 art\u0131rabilir, ancak bu durum mod\u00fcler yakla\u015f\u0131mla y\u00f6netilebilir.<\/p>\n<h3>NGXS vs. NgRx (K\u0131sa Kar\u015f\u0131la\u015ft\u0131rma)<\/h3>\n<p>Angular ekosisteminde durum y\u00f6netimi denince akla gelen ilk \u00e7\u00f6z\u00fcmlerden biri NgRx&#8217;tir. NGXS ve NgRx benzer prensiplere dayan\u0131r ancak farkl\u0131 uygulama yakla\u015f\u0131mlar\u0131 sunarlar:<\/p>\n<p>*   <strong>Boilerplate:<\/strong> NGXS, dekorat\u00f6r tabanl\u0131 yap\u0131s\u0131 sayesinde NgRx&#8217;e g\u00f6re daha az boilerplate kod gerektirir. NgRx, action, reducer, effect ve selector&#8217;lar\u0131 ayr\u0131 ayr\u0131 tan\u0131mlamay\u0131 gerektirirken, NGXS bunlar\u0131 tek bir <code>State<\/code> s\u0131n\u0131f\u0131 i\u00e7inde birle\u015ftirir.<br \/>\n*   <strong>\u00d6\u011frenme E\u011frisi:<\/strong> NGXS genellikle NgRx&#8217;e g\u00f6re daha h\u0131zl\u0131 \u00f6\u011frenilebilir ve ba\u015flang\u0131\u00e7 i\u00e7in daha az karma\u015f\u0131kt\u0131r. NgRx&#8217;in daha kat\u0131 Redux prensipleri ve daha fazla soyutlama katman\u0131 vard\u0131r.<br \/>\n*   <strong>Kod Yap\u0131s\u0131:<\/strong> NGXS, TypeScript s\u0131n\u0131flar\u0131 ve dekorat\u00f6rler kullanarak daha &#8220;Angular-vari&#8221; bir kodlama deneyimi sunar. NgRx, daha fonksiyonel bir yakla\u015f\u0131m\u0131 benimser.<br \/>\n*   <strong>Kontrol ve Esneklik:<\/strong> NgRx, Redux&#8217;\u0131n t\u00fcm g\u00fcc\u00fcn\u00fc ve esnekli\u011fini sunar, bu da \u00e7ok karma\u015f\u0131k senaryolarda daha fazla kontrol sa\u011flayabilir. NGXS ise daha h\u0131zl\u0131 geli\u015ftirme ve daha az kod ile benzer sonu\u00e7lar elde etmeyi hedefler.<br \/>\n*   <strong>Topluluk ve Olgunluk:<\/strong> NgRx, daha uzun bir ge\u00e7mi\u015fe sahip oldu\u011fu i\u00e7in daha b\u00fcy\u00fck bir toplulu\u011fa, daha fazla kayna\u011fa ve daha olgun bir ekosisteme sahiptir. NGXS ise h\u0131zla b\u00fcy\u00fcyen ve aktif bir toplulu\u011fa sahiptir.<\/p>\n<p>Se\u00e7im, projenin b\u00fcy\u00fckl\u00fc\u011f\u00fc, tak\u0131m\u0131n RxJS ve Redux deneyimi, tercih edilen kodlama stili ve geli\u015ftirme h\u0131z\u0131 gibi fakt\u00f6rlere ba\u011fl\u0131d\u0131r. Daha h\u0131zl\u0131 bir ba\u015flang\u0131\u00e7 ve daha az kod arayanlar i\u00e7in NGXS harika bir se\u00e7enek olabilirken, Redux prensiplerine tam ba\u011fl\u0131l\u0131k ve maksimum kontrol isteyenler NgRx&#8217;i tercih edebilir.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Angular uygulamalar\u0131nda durum y\u00f6netimi, uygulaman\u0131n karma\u015f\u0131kl\u0131\u011f\u0131 artt\u0131k\u00e7a hayati bir rol oynar. NGXS, modern Angular geli\u015ftiricilerine g\u00fc\u00e7l\u00fc, \u00f6l\u00e7eklenebilir ve bak\u0131m\u0131 kolay durum y\u00f6netimi \u00e7\u00f6z\u00fcmleri sunan m\u00fckemmel bir k\u00fct\u00fcphanedir. TypeScript ve RxJS&#8217;in g\u00fcc\u00fcn\u00fc kullanarak, az boilerplate kod ile temiz ve okunabilir bir kod taban\u0131 olu\u015fturman\u0131za olanak tan\u0131r.<\/p>\n<p>Bu makalede ele ald\u0131\u011f\u0131m\u0131z temel kavramlar, kurulum, state, action, selector ve asenkron i\u015flem y\u00f6netimi gibi konular, NGXS ile durum y\u00f6netimine ba\u015flamak i\u00e7in sa\u011flam bir temel olu\u015fturmaktad\u0131r. Plugin deste\u011fi ve mod\u00fcler yap\u0131s\u0131 sayesinde b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalar\u0131n bile durumunu etkin bir \u015fekilde y\u00f6netebilirsiniz. NGXS, geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131rken, uygulaman\u0131z\u0131n performans\u0131n\u0131 ve s\u00fcrd\u00fcr\u00fclebilirli\u011fini art\u0131rmaya yard\u0131mc\u0131 olan de\u011ferli bir ara\u00e7t\u0131r. Gelecek Angular projelerinizde durum y\u00f6netimi ihtiyac\u0131n\u0131z oldu\u011funda NGXS&#8217;i de\u011ferlendirmeniz, size \u00f6nemli avantajlar sa\u011flayacakt\u0131r.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler\nGiri\u015f\nModern web uygulamalar\u0131, \u00f6zellikle Angular gibi","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1488],"tags":[],"class_list":{"0":"post-39467","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-angular","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler\" \/>\n<meta property=\"og:description\" content=\"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler Giri\u015f Modern web uygulamalar\u0131, \u00f6zellikle Angular gibi\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-22T01:40:51+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler\",\"datePublished\":\"2026-02-22T01:40:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\"},\"wordCount\":2696,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Angular\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\",\"name\":\"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-02-22T01:40:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/","og_locale":"tr_TR","og_type":"article","og_title":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler","og_description":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler Giri\u015f Modern web uygulamalar\u0131, \u00f6zellikle Angular gibi","og_url":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-02-22T01:40:51+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"21 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler","datePublished":"2026-02-22T01:40:51+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/"},"wordCount":2696,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Angular"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/","url":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/","name":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-02-22T01:40:51+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinda-durum-yonetimi-ngxs-ile-guclu-ve-olceklenebilir-cozumler\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Angular Uygulamalar\u0131nda Durum Y\u00f6netimi: NGXS ile G\u00fc\u00e7l\u00fc ve \u00d6l\u00e7eklenebilir \u00c7\u00f6z\u00fcmler"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/39467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=39467"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/39467\/revisions"}],"predecessor-version":[{"id":39468,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/39467\/revisions\/39468"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=39467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=39467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=39467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}