Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
riverpodを理解したい
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
tatsubee
October 26, 2023
Technology
210
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
330
Create Spatial Photo with ImagePresentationComponent
shoryuyamamoto
0
110
pixivのリアーキテクチャにおける The Composable Architecter活用
shoryuyamamoto
0
220
pixivアプリは変化する
shoryuyamamoto
0
1.2k
マルチウィンドウでアプリケーションの表現を拡張する
shoryuyamamoto
1
440
【After iOSDC LT Night〜ピクシブ×日経×タイミー〜】実装!Interactive Widgets
shoryuyamamoto
0
82
SwiftPM マルチモジュール構成への第一歩
shoryuyamamoto
0
3.4k
TCA with UIKit [TCAでわいわいLT会]
shoryuyamamoto
1
1.5k
Dart Macrosに願いを [YOUTRUST x ゆめみ Flutter LT会@渋谷 #4]
shoryuyamamoto
0
920
Other Decks in Technology
See All in Technology
魔法少女がClaude Codeを監視する / ccportal-deck
noriyukitakei
3
110
When Token Pruning is Worse than Random: Understanding Visual Token Information in VLLMs
sansantech
PRO
0
220
みてねにおけるAI-DLC導入活動とAIドリブン開発の現在地/JAWS-UG AI-DLC #2
isaoshimizu
2
320
分割40%キーボードにスムーズに入門するには
hoto17296
1
210
The Django UUID Story - DjangoCon US 2026
pauloxnet
0
370
Cloudflare製品を活用した AIガバナンス実践入門 / AI governance with Cloudflare Service
delta_tech
1
180
IDperturb: Enhancing Variation in Synthetic Face Generation via Angular Perturbation
sansantech
PRO
0
100
いま、生成AIにKaggleをどこまで 任せられるか — ROGIIコンペでの進め方とTips
k951286
1
780
書籍『生成AIの安全性入門』の入門
wataoka
0
150
アクセスキー流出時の対応で再認識した攻撃側と防御側の非対称性について
kazzpapa3
1
510
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
5k
markdown-poster Introduction
kazamori
0
460
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Building an army of robots
kneath
306
46k
Are puppies a ranking factor?
jonoalderson
2
3.9k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
480
Writing Fast Ruby
sferik
630
63k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
540
The agentic SEO stack - context over prompts
schlessera
0
880
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
230
A Soul's Torment
seathinner
7
3.5k
Practical Orchestrator
shlominoach
191
12k
Automating Front-end Workflow
addyosmani
1369
210k
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サーバー