Upgrade to Pro — share decks privately, control downloads, hide ads and more …

チームで採用しているriverpodを使ったFlutterのアーキテクチャとriverpod v1.0.0

チームで採用しているriverpodを使ったFlutterのアーキテクチャとriverpod v1.0.0

Bd34d8c4bc464a2bec2792579c759cd1?s=128

Kakeru Nakabachi

August 06, 2021
Tweet

Transcript

  1. チームで採用しているriverpodを使った Flutterのアーキテクチャとriverpod v1.0.0 b4tchkn Flutter x Kotlin Multiplatform by CyberAgent

    #4 2021/08/06 #ca_flutter_kmm
  2. About me Kakeru Nakabachi batch(@b4tchkn) 2

  3. 今日のゴール • ちょっとこの部分参考にできるかも • riverpodで状態管理いいかも • CAもFlutterで色々やってるんだな👀 3

  4. アジェンダ • riverpodの簡単な紹介 • チームのFlutterプロジェクトアーキテクチャ • riverpod使用ルールについて 4

  5. riverpod 5

  6. • もともとあった、Providerという状態管理ライブラリの問題点を解消したやつ • DIもこれで実現できる • テスタブルなコードを保証してくれる • 最近 v1.0.0に乗り換え •

    hooks_riverpod • flutter_riverpod • riverpod https://riverpod.dev/docs/getting_started/ riverpod 6
  7. • もともとあった、Providerという状態管理ライブラリの問題点を解消したやつ • DIもこれで実現できる • テスタブルなコードを保証してくれる • 最近 v1.0.0に乗り換え •

    hooks_riverpod • flutter_riverpod • riverpod https://riverpod.dev/docs/getting_started/ riverpod 7
  8. hooks_riverpod flutter_hooksと併用する使い方 HookConsumerWidgetを使って中でref.watchなど便利メソッドが呼べる 8

  9. hooks_riverpod 公式にも載ってる簡単なサンプル 9

  10. hooks_riverpod riverpodを使うプロジェクトではAppを ProviderScopeでラップする 10

  11. hooks_riverpod Stringを配るProvider 11

  12. hooks_riverpod ProviderをWidget内で監視 12

  13. hooks_riverpod riverpod v1.0.0での割と大きな変更点 13

  14. チームのFlutterアーキテクチャ 14

  15. 全体像 15 UI State Domain Data

  16. 全体像 16 UI State Domain Data

  17. • Service ◦ DioとRetrofitを使った RemoteDataSource ◦ 定義したabstract class(interface)から実 際にリクエストするコードを生成 •

    Database ◦ SharedPreferencesを使った LocalDataSource ◦ Key - Valueでデータを永続化 同ドメインに関わる複数のメソッドを定義できる getArticle(String id)とか Data 17
  18. Data • 実際にリクエストするメソッド 18

  19. Data • Dioの依存をriverpodのProviderを使ってDI • Dioに依存したdatasourceのインスタンスをProviderで配布 19

  20. 全体像 20 UI State Domain Data

  21. Domain ビジネスオブジェクトを含む、アプリケーションの中核となるレイヤー メソッドは1つしか実装できない UseCaseは他のUseCaseへの参照はできない Stateが複数UseCaseを持つのはOK 21

  22. Domain UseCaseはDataSourceに依存 22

  23. Domain UseCaseはDataSourceに依存 DataSourceで定義したProviderを 使ってUseCaseのインスタンスを配 布する際にDIして提供する 23

  24. Domain DataSourceのコールにパラメータが必要 な場合 24

  25. Domain DataSourceのコールにパラメータが必要 な場合 パラメータが1つでもUseCaseParamのオ ブジェクトを作ってUseCaseに渡す 25

  26. 全体像 26 UI State Domain Data

  27. State 1つの状態だけを持つViewModel的な存在 Recoilの思想を取り入れて、1つのStateの粒度を可能な限り小さくする 27 https://recoiljs.org/

  28. State StateのProviderを作る時はStateNotifierProviderを使う 28

  29. State 29 トップ画面 記事一覧画面

  30. State UseCaseの依存解決にParamが必要な場合 familyを使ってProviderを作るパラメータを増やす このときParamが変更されると古いParamを持ったProviderは再利用されず溜まってい き、メモリリークの原因となるためautoDisposeもセットで使う 30

  31. Selector Stateをなにかしら計算してUIに渡したいときに定義 複数のStateを参照して計算した値をSelectorで定義してUIに配布もできる 31

  32. State よくあるStateの動き 32

  33. State よくあるStateの動き 33 loading Request Request

  34. よくあるStateの動き State 34 loading Data Data

  35. State よくあるStateの動き 35 idle(loaded) Data Data Data

  36. State よくあるStateの動き(異常系) 36 idle(loaded) Error Data Data

  37. State これらの状態をAsycEntity、 AsyncStateNotifierで表現 37

  38. 全体像 38 UI State Domain Data

  39. UI - Connected Screen StatefulなPage StateとStatelessなHogePageを繋ぎこむ役目 StateProviderの保持と、loadingなどの状態に よってWidgetを出し分けるため DefaultContainerでAsyncEntityの値を処理す る

    39
  40. UI - Connected Screen DefaultContainer Stateから渡ってきた複数のAsyncEntityの値を処理してWidgetの出し分けを担う 40 ロード中 ロード終了 エラー発生

  41. UI - Stateless Screen StateをもたないWidget群 • ListView • TextView •

    Container • Column • … 41
  42. riverpod使用ルール 42

  43. riverpod使用ルール Providerの作り方はたくさんある • Provider • StreamProvider • StateProvider • StateNotifierProvider

    • FutureProvider https://riverpod.dev/docs/concepts/providers 43
  44. Providerのreadの仕方もいっぱいある https://riverpod.dev/docs/concepts/reading riverpod使用ルール 44

  45. riverpod使用ルール ルール①:FutureProvider / StreamProviderの代わりに StateNotifierProvider+AsyncStateNotifier 45 NG OK

  46. riverpod使用ルール ルール②:StateProviderの代わりにStateNotifierProvider+StateController 46 NG OK

  47. riverpod使用ルール ルール③:Provider作成時はref.readは使わないでref.watchのみで統一 47 NG OK

  48. riverpod使用ルール ▪ まとめ 1. FutureProvider / StreamProviderの代わりに StateNotifierProvider+AsyncStateNotifier 2. StateProviderの代わりにStateNotifierProvider+StateController

    ➢ プロジェクトで使うProviderをProviderとStateNotifierProviderに制限 3. Provider作成時はref.readは使わないでref.watchのみで統一 ➢ 依存しているProviderが再生成されたときに、変化した値を購読できるよ うにするため ➢ 設計の統一性、Providerの依存を見やすくする 48
  49. 参考リンク 49 • https://riverpod.dev/docs/getting_started • https://recoiljs.org/ • https://zenn.dev/riscait/books/flutter-riverpod-practical-introduction/viewer/mig rate-to-v1

  50. Thank you 50