Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
riverpodを理解したい
Search
tatsubee
October 26, 2023
Technology
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
riverpodを理解したい
tatsubee
October 26, 2023
More Decks by tatsubee
See All by tatsubee
マルチウィンドウ実践ガイド
shoryuyamamoto
0
350
Create Spatial Photo with ImagePresentationComponent
shoryuyamamoto
0
120
pixivのリアーキテクチャにおける The Composable Architecter活用
shoryuyamamoto
0
230
pixivアプリは変化する
shoryuyamamoto
0
1.2k
マルチウィンドウでアプリケーションの表現を拡張する
shoryuyamamoto
1
450
【After iOSDC LT Night〜ピクシブ×日経×タイミー〜】実装!Interactive Widgets
shoryuyamamoto
0
86
SwiftPM マルチモジュール構成への第一歩
shoryuyamamoto
0
3.4k
TCA with UIKit [TCAでわいわいLT会]
shoryuyamamoto
1
1.5k
Dart Macrosに願いを [YOUTRUST x ゆめみ Flutter LT会@渋谷 #4]
shoryuyamamoto
0
930
Other Decks in Technology
See All in Technology
HacobuにおけるFDEとは/登壇資料(戸井田 裕貴)
hacobu
PRO
1
120
Account Factory for Terraformによる 標準化されたアカウント発行の自動化
pensuke628
0
110
AIエージェント時代のPlatform as a Product —— テックリードがPdMとして回す発見・導入・計測 / Platform as a Product in the AI Agent Era
toshi0607
1
400
Argo CDとAtlantisで実現するインフラ管理のセルフサービス化──小規模SREチームで支えるプラットフォーム
cassius7
0
190
手を動かして実感する、Kiro が変える開発体験
inariku
0
390
高負荷プロダクション環境におけるAWS Lambdaのリアル 〜スケールとコストを左右する実行ライフサイクルの技術仕様〜
maimyyym
2
710
Making AI Agents Safe and Fast- Jev, Obsidian, and the Meta-Harness
x5gtrn
PRO
0
150
spanner-autoscalerに学ぶ CRD設計パターン 〜自動化と緊急時対応を両立する Kubernetesコントローラーの作り方〜
tkuchiki
0
180
LT:「このままでいいのかな?」から一歩踏み出した私のデータキャリア選択〜社会人3年目に上京を決意したリアル〜Snowflake女子会 vol.8
snowwmn0824
0
110
Claude Codeを「使うほど育つ」AI秘書にするノウハウ
minorun365
PRO
32
33k
Apache Iceberg が拓く AI 時代のオープンレイクハウス
tomtanaka
0
110
AWS App Runnerから Cloudflare Workersへ移行した話
ryota09
0
110
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
10k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
How to make the Groovebox
asonas
2
2.5k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
310
Between Models and Reality
mayunak
4
470
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
290
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
880
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
It's Worth the Effort
3n
188
29k
sira's awesome portfolio website redesign presentation
elsirapls
0
420
Done Done
chrislema
187
17k
Transcript
riverpodを理解したい pixiv Inc. tatsubee 2023.10.26
2 自己紹介 • 23新卒 • 福岡生まれ 福岡育ち 東京在住 • 最近やっていること
◦ お絵描き ◦ テニス ◦ iOS tatsubee iOSエンジニア
3 初めにちょっとだけ宣伝
4
5 福岡のFlutterコミュニティ 様々なイベントを開催して活発に活動中! • 月一でのLTイベント開催 • 先日の東京Flutterハッカソンへの参加 • その他内輪の勉強会 などなど
6 福岡のFlutterコミュニティ 様々なイベントを開催して活発に活動中!!! • 月一でのLTイベント開催 • 東京Flutterハッカソンへの参加 • その他内輪の勉強会 などなど
7 本題
8 riverpod勉強会 Fukuoka Flutter Fanclubで毎週やっている勉強会 目標: riverpodを「作れる」レベルのコード理解 ↓を順に、1時間でできる範囲でドキュメントやコードを読み進めていく • riverpodでできることの把握
• InheritedWidgetのコード理解 • providerのコード理解 • riverpodのコード理解
9 riverpod勉強会 Fukuoka Flutter Fanclubで毎週やっている勉強会 目標: riverpodを「作れる」レベルのコード理解 ↓を順に、1時間でできる範囲でドキュメントやコードを読み進めていく • riverpodでできることの把握
• InheritedWidgetのコード理解 ←ここまで進んだ • providerのコード理解 • riverpodのコード理解
10 このLTの内容 riverpod
11 このLTの内容 riverpod InheritedWidget
12 InheritedWidget 特徴 • 祖先のWidgetが管理する値にO(1)でアクセスできる • 値を購読する子孫のWidgetに、その値の変更を通知することができる (riverpodやproviderがあるので直接扱う必要性はない)
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 13 InheritedWidget
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 14 InheritedWidget class Child extends StatelessWidget { const Child({super.key}); @override Widget build(BuildContext context) => Text('${CountInherited.of(context).count}'); }
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 15 InheritedWidget class CountInherited extends InheritedWidget { const CountInherited({ super.key, required this.count, required super.child, }); final int count; static CountInherited of(BuildContext context) => context.dependOnInheritedWidgetOfExactType()!; @override bool updateShouldNotify(CountInherited oldWidget) => oldWidget.count != count; }
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 16 InheritedWidget
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 17 InheritedWidget
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 18 InheritedWidget
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 19 InheritedWidget
20 InheritedWidgetの 中身を覗いてみる
abstract class InheritedWidget extends ProxyWidget { const InheritedWidget({ super.key, required
super.child }); @override InheritedElement createElement() => InheritedElement(this); @protected bool updateShouldNotify(covariant InheritedWidget oldWidget); } 21 InheritedElementの作成と 変更の通知の判定のみ!
class InheritedElement extends ProxyElement { InheritedElement(InheritedWidget super.widget); final Map<Element, Object?>
_dependents = HashMap<Element, Object?>(); @override void _updateInheritance() {...} @override void debugDeactivated() {...} @protected Object? getDependencies(Element dependent) {...} @protected void updateDependencies(Element dependent, Object? aspect) {...} @protected void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {...} @override void updated(InheritedWidget oldWidget) {...} @override void notifyClients(InheritedWidget oldWidget) {...} } 22
23 O(1)でアクセスする仕組み
24 アクセス方法
abstract class Element extends DiagnosticableTree implements BuildContext { PersistentHashMap<Type, InheritedElement>?
_inheritedElements; @override T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({ Object? aspect }) { final InheritedElement? ancestor = _inheritedElements == null ? null : _inheritedElements![T]; if (ancestor != null) { return dependOnInheritedElement(ancestor, aspect: aspect) as T; } _hadUnsatisfiedDependencies = true; return null; } } 25 = watch
abstract class Element extends DiagnosticableTree implements BuildContext { PersistentHashMap<Type, InheritedElement>?
_inheritedElements; @override T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({ Object? aspect }) { final InheritedElement? ancestor = _inheritedElements == null ? null : _inheritedElements![T]; if (ancestor != null) { return dependOnInheritedElement(ancestor, aspect: aspect) as T; } _hadUnsatisfiedDependencies = true; return null; } } 26 自身が持っている_inheritedElements の中から 型が一致するInheritedElementを返す = watch
27 _inheritedElementsへの格納
abstract class Element extends DiagnosticableTree implements BuildContext { @mustCallSuper void
mount(Element? parent, Object? newSlot) { _updateInheritance(); } } 28
abstract class Element extends DiagnosticableTree implements BuildContext { void _updateInheritance()
{ _inheritedElements = _parent?._inheritedElements; } } class InheritedElement extends ProxyElement { @override void _updateInheritance() { final PersistentHashMap<Type, InheritedElement> incomingWidgets = _parent?._inheritedElements ?? const PersistentHashMap<Type, InheritedElement>.empty(); _inheritedElements = incomingWidgets.put(widget.runtimeType, this); } } 29
abstract class Element extends DiagnosticableTree implements BuildContext { void _updateInheritance()
{ _inheritedElements = _parent?._inheritedElements; } } class InheritedElement extends ProxyElement { @override void _updateInheritance() { final PersistentHashMap<Type, InheritedElement> incomingWidgets = _parent?._inheritedElements ?? const PersistentHashMap<Type, InheritedElement>.empty(); _inheritedElements = incomingWidgets.put(widget.runtimeType, this); } } 30 親の_inheritedElenentsを そのまま引き継ぐ
abstract class Element extends DiagnosticableTree implements BuildContext { void _updateInheritance()
{ _inheritedElements = _parent?._inheritedElements; } } class InheritedElement extends ProxyElement { @override void _updateInheritance() { final PersistentHashMap<Type, InheritedElement> incomingWidgets = _parent?._inheritedElements ?? const PersistentHashMap<Type, InheritedElement>.empty(); _inheritedElements = incomingWidgets.put(widget.runtimeType, this); } } 31 親から引き継いだ _inheritedElenentsに 自身を挿入する
32 視覚的に見てみると...
33 Parent CounterInherited Child Widgetツリー { } { CounterInherited: InheritedElement
} _inheritedElements { CounterInherited: InheritedElement }
34 Parent CounterInherited Child Widgetツリー { } { CounterInherited: InheritedElement
} _inheritedElements { CounterInherited: InheritedElement } アクセス
35 変更を通知する仕組み
36 countの値を変更する時
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 37
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 38 リビルド範囲
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 39 リビルド範囲
class Parent extends StatefulWidget { … } class _ParentState extends
State<Parent> { int count = 0; @override Widget build(BuildContext context) { return CountInherited( count: count, child: Scaffold( body: const Center( child: Child(), ), floatingActionButton: FloatingActionButton( onPressed: () => setState(() { count++; }), ), ), ); } } 40 リビルド範囲 リビルドされない constによってリビルドが抑 制される
class Child extends StatelessWidget { const Child({super.key}); @override Widget build(BuildContext
context) => Text('${CountInherited.of(context).count}'); } 41
class Child extends StatelessWidget { const Child({super.key}); @override Widget build(BuildContext
context) => Text('${CountInherited.of(context).count}'); } 42 StatefulWidgetの方が わかりやすいので変換
class Child extends StatefulWidget { … } class _ChildState extends
State<Child> { @override void didChangeDependencies() { … } @override Widget build(BuildContext context) { final countInherited = context.dependOnInheritedWidgetOfExactType()! as CountInherited; return Text('${countInherited.count}); } } 43 StatefulWidgetの方が わかりやすいので変換
class Child extends StatefulWidget { … } class _ChildState extends
State<Child> { @override void didChangeDependencies() { … } @override Widget build(BuildContext context) { final countInherited = context.dependOnInheritedWidgetOfExactType()! as CountInherited; return Text('${countInherited.count}); } } 44 setStateされると didChangeDependencies が発火!
class Child extends StatefulWidget { … } class _ChildState extends
State<Child> { @override void didChangeDependencies() { … } @override Widget build(BuildContext context) { final countInherited = context.dependOnInheritedWidgetOfExactType()! as CountInherited; return Text('${countInherited.count}); } } 45 ”Dependencies”とは、 InheritedWidgetのこと!
46 時間がなさそうなのでここまで! 気になる方は懇親会で!
class InheritedElement extends ProxyElement { InheritedElement(InheritedWidget super.widget); final Map<Element, Object?>
_dependents = HashMap<Element, Object?>(); @override void _updateInheritance() {...} @override void debugDeactivated() {...} @protected Object? getDependencies(Element dependent) {...} @protected void updateDependencies(Element dependent, Object? aspect) {...} @protected void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {...} @override void updated(InheritedWidget oldWidget) {...} @override void notifyClients(InheritedWidget oldWidget) {...} } 47
class InheritedElement extends ProxyElement { InheritedElement(InheritedWidget super.widget); final Map<Element, Object?>
_dependents = HashMap<Element, Object?>(); @override void _updateInheritance() {...} @override void debugDeactivated() {...} @protected Object? getDependencies(Element dependent) {...} @protected void updateDependencies(Element dependent, Object? aspect) {...} @protected void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {...} @override void updated(InheritedWidget oldWidget) {...} @override void notifyClients(InheritedWidget oldWidget) {...} } 48 Log setState ParentWidget.build InheritedElement.updated InheritedWidget.updateShouldNotify:true InheritedWidget.updateShouldNotify:true InheritedElement.notifyClients InheritedElement.notifyDependent ChildWidget.didChangeDependencies ChildWidget.build InheritedElement.updateDependencies InheritedElement.setDependencies
49 ありがとうございました!
50 魂だけでも福岡に送ってみませんか? Discordサーバー