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
360
Create Spatial Photo with ImagePresentationComponent
shoryuyamamoto
0
120
pixivのリアーキテクチャにおける The Composable Architecter活用
shoryuyamamoto
0
240
pixivアプリは変化する
shoryuyamamoto
0
1.2k
マルチウィンドウでアプリケーションの表現を拡張する
shoryuyamamoto
1
450
【After iOSDC LT Night〜ピクシブ×日経×タイミー〜】実装!Interactive Widgets
shoryuyamamoto
0
87
SwiftPM マルチモジュール構成への第一歩
shoryuyamamoto
0
3.4k
TCA with UIKit [TCAでわいわいLT会]
shoryuyamamoto
1
1.5k
Dart Macrosに願いを [YOUTRUST x ゆめみ Flutter LT会@渋谷 #4]
shoryuyamamoto
0
940
Other Decks in Technology
See All in Technology
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
1
1.8k
実践!Cloud Run ハンズオン!! / Cloud Run handson
y0hgi
1
260
UniFi(ユニファイ)AIカメラの現場活用
ludicmind
1
420
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.5k
LocalStack を使ったサーバーレスアプリケーション開発 / Serverless Development with LocalStack
kakakakakku
1
420
FactoryBotアンチパターン / factory_bot anti-patterns
toshimaru
0
160
AI 時代の Azure エンジニアリング ~ 私たちは何を磨き、何を任せるのか ~
chack411
1
610
大型犬好きによるPugの紹介
yamanoku
1
150
Classmethod Company Deck
satoshi7
0
170
「Docker Desktop不要の時代」は 来たのか?
ueponx
0
620
AI時代のAPI開発を加速する品質ガードレール / API Quality Guardrails in the AI Era
yokawasa
0
190
ai_cording_with_k8s_knowledge.pdf
mochizuki875
1
350
Featured
See All Featured
Become a Pro
speakerdeck
PRO
31
6.3k
HDC tutorial
michielstock
2
960
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
560
Why Our Code Smells
bkeepers
PRO
340
58k
The browser strikes back
jonoalderson
0
1.8k
The Curious Case for Waylosing
cassininazir
1
570
Discover your Explorer Soul
emna__ayadi
2
1.3k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
450
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
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サーバー