﻿
{"id":26653,"date":"2023-10-25T20:23:58","date_gmt":"2023-10-25T20:23:58","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=26653"},"modified":"2023-10-25T20:23:58","modified_gmt":"2023-10-25T20:23:58","slug":"angular-16-signals-state-management","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/angular-16-signals-state-management\/","title":{"rendered":"Angular 16 Signals &#8211; State Management"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde, Angular 16 ile gelmi\u015f olan <a href=\"https:\/\/www.gencayyildiz.com\/blog\/angular-16-signals-yapilanmasini-detayli-inceleyelim\/\" rel=\"noopener\" target=\"_blank\">Signals<\/a> yap\u0131lanmas\u0131n\u0131 kullanarak state management&#8217;\u0131n nas\u0131l uygulanabilece\u011fini inceliyor olaca\u011f\u0131z.<\/p>\n<p>Angular mimarisi, yap\u0131sal olarak fazlas\u0131yla kurall\u0131 bir anatomiye sahip olsa da, esas\u0131nda temel mant\u0131\u011f\u0131 anla\u015f\u0131ld\u0131\u011f\u0131 taktirde olduk\u00e7a kolay ve geli\u015ftirici dostu bir yap\u0131ya sahiptir. Haliyle bu tarz zahiren komplike g\u00f6z\u00fcken bir mimaride mevzu bahis state management oldu\u011funda da ister istemez bir karma\u015f\u0131kl\u0131k s\u00f6z konusu olabilmektedir.<\/p>\n<p>Do\u011frusu b\u00fcy\u00fck projelerde state management&#8217;\u0131 sa\u011flayabilmek i\u00e7in basitlik ilkesi gere\u011fi m\u00fcmk\u00fcn mertebe sade bir yakla\u015f\u0131m sergilenmesine ve olduk\u00e7a sadece ihtiya\u00e7 olan state&#8217;lerin y\u00f6netilmesine odaklan\u0131lmas\u0131 gerekti\u011fi kanaatindeyim.<\/p>\n<p>Bunun i\u00e7in tercihen <em>NgRx<\/em> ba\u015fta olmak \u00fczere <em>Akita<\/em> ve <em>MobX<\/em> gibi haz\u0131r k\u00fct\u00fcphanelerden istifade edilebilece\u011fi gibi esas\u0131nda bu k\u00fct\u00fcphanelerin getirdi\u011fi karma\u015f\u0131kl\u0131k ve basmakal\u0131p(boilerplate) yap\u0131lanmalardan ka\u00e7\u0131nmak i\u00e7in herhangi bir framework&#8217;e ihtiya\u00e7 duyulmaks\u0131z\u0131n Angular mimarisinin injectable servislerinden istifade edilmesi gerekti\u011fine dair son zamanlarda kanaat getiriyor gibiyim&#8230; \u00c7\u00fcnk\u00fc injectable service&#8217;ler; reaktiftirler, ba\u015flang\u0131\u00e7 de\u011ferleri mevcuttur ve yaz\u0131lmalar\u0131, geli\u015ftirilmeleri ve bak\u0131mlar\u0131 olduk\u00e7a kolay ve maliyetsizdirler.<\/p>\n<p>Zamanla anlad\u0131m ki, projenin hacmi ne olursa olsun, state management i\u00e7in <em>actions<\/em>, <em>action types<\/em>, <em>reducers<\/em>, <em>selectos<\/em>, <em>effects<\/em> vs. gibi terminolojik terimlerin \u00f6\u011frenilmesine ve ayr\u0131ca bunlar\u0131n kullan\u0131l\u0131p, y\u00f6netilme zahmetinin verilmesine san\u0131r\u0131m hi\u00e7te gerek yokmu\u015f. Ayr\u0131ca NgRx&#8217;den yola \u00e7\u0131karsak e\u011fer arka planda kulland\u0131\u011f\u0131 <code>BehaviorSubject<\/code> a\u015fa\u011f\u0131daki kimi dezavantajlar\u0131 da bar\u0131nd\u0131rd\u0131\u011f\u0131 i\u00e7in ister istemez bu kanaatim hakk\u0131nda hakl\u0131l\u0131k pay\u0131m\u0131 da g\u00f6rmedim de\u011fil;<\/p>\n<ul>\n<li>RxJS&#8217;i son derece iyi bilmeyi gerektirmektedir.<\/li>\n<li>Uzun s\u00fcreli veya b\u00fcy\u00fck veri ak\u0131\u015flar\u0131nda \u00e7al\u0131\u015f\u0131rken fazlas\u0131yla bellek t\u00fcketimi ve hatta bellek s\u0131z\u0131nt\u0131lar\u0131(memory leaks) s\u00f6z konusu olabilir.<\/li>\n<li>Birden fazla i\u015f par\u00e7ac\u0131\u011f\u0131 veya asenkron i\u015flem s\u00f6z konusu oldu\u011fu durumlarda, senkronizasyon veya g\u00fcvenilirlik sorunlar\u0131 s\u00f6z konusu olabilir.<\/li>\n<\/ul>\n<p>Haliyle t\u00fcm bu kayg\u0131lara kar\u015f\u0131n, injectable service&#8217;lere nazaran de\u011fi\u015fiklik alg\u0131lama ve senkronizasyon a\u00e7\u0131s\u0131ndan olduk\u00e7a optimize edilmi\u015f olan ve anl\u0131k olarak de\u011ferini her daim okuyabilme(snapshot) imkan\u0131m\u0131z olan signal yap\u0131lanmas\u0131n\u0131 da state management s\u00fcre\u00e7lerinde tercih edebiliriz.<\/p>\n<p>Bunun i\u00e7in signal tabanl\u0131 bir store tasarlamam\u0131z yeterli olacakt\u0131r. Bunu da a\u015fa\u011f\u0131daki gibi bir component&#8217;te girilen person bilgilerinin, ba\u015fka bir component&#8217;te listelendi\u011fi basit bir senaryo \u00e7al\u0131\u015fmas\u0131 \u00fczerinden inceleyebiliriz.<\/p>\n<p>\u015eimdi <em>CreatePersonComponent<\/em> ve <em>ListPersonComponent<\/em> ad\u0131nda iki component&#8217;e ve <em>PersonStateManagementService<\/em> ad\u0131nda da bir service&#8217;a sahip bir uygulama tasarlayal\u0131m.<\/p>\n<div style=\"text-align:center;\">\n<code><strong><em>ng g c components\/createPerson --standalone<\/em><\/strong><\/code><br \/>\n<code><strong><em>ng g c components\/listPerson --standalone<\/em><\/strong><\/code><br \/>\n<code><strong><em>ng g s services\/personStateManagement<\/em><\/strong><\/code>\n<\/div>\n<p>\u0130lk olarak <em>PersonStateManagementService<\/em>&#8216;ini a\u015fa\u011f\u0131daki gibi geli\u015ftirelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Injectable, WritableSignal, signal } from '@angular\/core';\r\n\r\n@Injectable({\r\n  providedIn: 'root'\r\n})\r\nexport class PersonStateManagementService {\r\n\r\n  constructor() { }\r\n\r\n  persons: WritableSignal&lt;{ name: string, surname: string }&#x5B;]&gt; = signal(&#x5B;]);\r\n  createPerson(name: string, surname: string) {\r\n    this.persons.mutate(datas =&gt; datas.push({\r\n      name: name, surname: surname\r\n    }))\r\n  }\r\n\r\n  getPersons() {\r\n    return this.persons();\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>Yukar\u0131daki \u00e7al\u0131\u015fmaya g\u00f6z atarsan\u0131z e\u011fer <em><strong>10.<\/strong><\/em> sat\u0131rda olu\u015fturulmu\u015f olan &#8216;persons&#8217; isimli signal i\u00e7erisindeki koleksiyona, &#8216;createPerson&#8217; metodunda name ve surname bilgileri gelen person nesnesi eklenmekte, &#8216;getPersons&#8217; metodunda ise bu signal&#8217;\u0131n de\u011feri olan koleksiyon geriye d\u00f6nd\u00fcr\u00fclmektedir.<\/p>\n<p>\u015eimdi olu\u015fturdu\u011fumuz component&#8217;lerin i\u00e7eriklerini s\u0131ras\u0131yla a\u015fa\u011f\u0131daki gibi geli\u015ftirelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, inject } from '@angular\/core';\r\nimport { CommonModule } from '@angular\/common';\r\nimport { PersonStateManagementService } from 'src\/app\/services\/person-state-management.service';\r\n\r\n@Component({\r\n  selector: 'app-create-person',\r\n  standalone: true,\r\n  imports: &#x5B;CommonModule],\r\n  template: `\r\n    &lt;input type=&quot;text&quot; #txtName placeholder=&quot;Name&quot;&gt; &lt;br&gt;\r\n    &lt;input type=&quot;text&quot; #txtSurname placeholder=&quot;Surname&quot;&gt; &lt;br&gt;\r\n    &lt;button (click)=&quot;createPerson(txtName.value, txtSurname.value)&quot;&gt;Create Person&lt;\/button&gt;\r\n  `,\r\n})\r\nexport class CreatePersonComponent {\r\n  personStateManagementService: PersonStateManagementService = inject(PersonStateManagementService);\r\n  createPerson(name: string, surname: string) {\r\n    this.personStateManagementService.createPerson(name, surname);\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, OnInit, inject } from '@angular\/core';\r\nimport { CommonModule } from '@angular\/common';\r\nimport { PersonStateManagementService } from 'src\/app\/services\/person-state-management.service';\r\n\r\n@Component({\r\n  selector: 'app-list-person',\r\n  standalone: true,\r\n  imports: &#x5B;CommonModule],\r\n  template: `\r\n    &lt;ul&gt;\r\n      &lt;li *ngFor=&quot;let person of persons&quot;&gt;{{person.name}} {{person.surname}}&lt;\/li&gt;\r\n    &lt;\/ul&gt;\r\n  `,\r\n})\r\nexport class ListPersonComponent implements OnInit {\r\n  personStateManagementService: PersonStateManagementService = inject(PersonStateManagementService);\r\n\r\n\r\n  persons: { name: string, surname: string }&#x5B;];\r\n  ngOnInit() {\r\n    this.persons = this.personStateManagementService.getPersons()\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <em>CreatePersonComponent<\/em>&#8216;te eklenen person bilgileri, signal tabanl\u0131 servis sayesinde <em>ListPersonComponent<\/em>&#8216;e dinamik bir \u015fekilde aktar\u0131lmaktad\u0131r. Ya da bir ba\u015fka deyi\u015fle person ekleme durumu neticesinde olu\u015fan de\u011fi\u015fiklik anl\u0131k olarak listelemeden sorumlu olan component&#8217;e yans\u0131t\u0131lmaktad\u0131r.<\/p>\n<p>Evet, anlayaca\u011f\u0131n\u0131z herhangi bir third party library kullanmaks\u0131z\u0131n Angular uygulamalar\u0131nda state management&#8217;\u0131n signal&#8217;lar ile nas\u0131l y\u00f6netilebilece\u011fini g\u00f6rm\u00fc\u015f ve \u00f6zellikle b\u00fcy\u00fck projelerde basit ve sade bir yakla\u015f\u0131mla bu i\u015flemin yap\u0131labilece\u011fini vurgulam\u0131\u015f olduk. Bu yakla\u015f\u0131m ile karma\u015f\u0131kl\u0131k azalt\u0131l\u0131rken, projelerin daha etkili ve verimli bir \u015fekilde geli\u015ftirilmesine olanak tan\u0131nd\u0131\u011f\u0131na sizlerin de kanaat getirdi\u011fini d\u00fc\u015f\u00fcn\u00fcyorum.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not: \u00d6rnek \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki github adresinden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/StateManagementExampleInAngular\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/StateManagementExampleInAngular<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde, Angular 16 ile gelmi\u015f olan Signals yap\u0131lanmas\u0131n\u0131 kullanarak state management&#8217;\u0131n nas\u0131l uygulanabilece\u011fini inceliyor olaca\u011f\u0131z. Angular mimarisi, yap\u0131sal olarak fazlas\u0131yla kurall\u0131 bir anatomiye sahip olsa da, esas\u0131nda temel mant\u0131\u011f\u0131 anla\u015f\u0131ld\u0131\u011f\u0131 taktirde olduk\u00e7a&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":26358,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2420,4796],"tags":[2156,4797,4799,4949,4951,4950],"class_list":["post-26653","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-angular-16","tag-angular","tag-angular-16","tag-angular-16-signals","tag-angular-16-signals-state-management","tag-signal-state-management","tag-signals-state-management"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26653","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=26653"}],"version-history":[{"count":8,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26653\/revisions"}],"predecessor-version":[{"id":26662,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26653\/revisions\/26662"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/26358"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=26653"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=26653"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=26653"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}