沒錯,又是另外一套 Angular 狀態管理的工具,這一套 Akita 根據介紹,是融合 Flux + Redux + RxJS 以 OOP 的方式呈現。有別於其他 Redux 風格的狀態管理,是以 FP 的方式完成,就來嘗鮮看看,多一種選擇也不錯
介紹
什麼是 Akita,Akita 是結合多家的精神,以物件導向的方格完成的狀態管理工具,減少產稱不必要的程式碼,讓習慣物件導向開發模式的人,也可以享受 Flux 風格的狀態管理方式
安裝 Akita
1 | yarn add @datorama/akita |
基本元素
(以下範例皆來自官方文件)
Model
Model 是用來描述 Store 內資料存放的結構。
1 | import { ID } from '@datorama/akita'; |
官方建議新增 type
和 factory function
,讓其負責 store 初始值的建立
Store
Store
是一個用來記載狀態的一個物件,建立一個 store
物件繼承 Akita Sotre
並傳入型別(Model) 被給予初始值
1 | import { Store, StoreConfig } from '@datorama/akita'; |
當建立 store
後,當在 service
使用時,可以透過 setState
的方式來更新 store 內的狀態
1 | setState(newStateFn: (state: Readonly<S>) => S) |
使用範例:
1 | import { SessionStore } from './session.store'; |
setState
的做法比較像是 redux 風格的 reducer,而 Akita 有提供另外一種方法可以快速地更新 Store 的值,
可透過 update
的方法來完成,update(newState: Partial<S>)
1 | import { SessionStore } from './session.store'; |
update
也可以接受 callback 方法。(詳情請閱讀官方文件)
也有其他的方法可以使用
setLoading(isLoading: boolean)
: 設定 store 的讀取狀態setError(error: any)
設定 store 的錯誤狀態
Service
Service 內的使用與一般在寫 Service 是一樣的,只是要將 store class 注入到 service 內使用
1 | import { SessionStore } from './session.store'; |
Query
Akita 的 Query 的地位,等同於 ngrx
的 selector,是用來撈取 Store 使用,回傳的型別為 Observable
1 | import { Query } from '@datorama/akita'; |
當繼承 Query<T>
時,會擁有 select<R>(project?: (store: S) => R): Observable<R>
的方法可以使用,雖然在 component 可透過 select
的方式讀取 store
的狀態,但一般建議是寫在 Query Class 內部,以方便重複使用
-
select()
方法回傳的 Observable 是會執行distinctUntilChanged()
的,這表示該select
只會當有資料異動時才會被觸發 -
selectOnce()
行為類似於select()
,但只會被觸發一次
1 | this.query.selectOnce(state=> state.key); |
-
getSnapshot()
回傳 store 的 raw value1
this.query.getSnapshot();
-
selectLoading()
: 取得 store 的 loading 狀態 -
selectError()
取得 store 的錯誤狀態
感想
雖然少了許多不必要的程式碼跟流程,但操作的複雜度似乎需要多花點時間研究,主要是 API 部分需要熟悉,這動作能不能自己刻,這當然是可以的,但透過學習其他的狀態管理工具並了解其背後的設計原理,也是有很大的幫助的。
單純就基本結構元素來看,Akita 所提供的 store
是比較關鍵的功能,其他的操作應該是大同小異。初步看來,真正的應用應該會是在 Entity
的地方,如何上用 Entity
來管理複雜的狀態會是需要思考的部分。
至於實際上怎麼使用,可以先參考這篇文章,先抓個感覺