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
Flutter HooksとRiverpodの解説
Search
Yohei Iino
June 16, 2024
580
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Flutter HooksとRiverpodの解説
Yohei Iino
June 16, 2024
More Decks by Yohei Iino
See All by Yohei Iino
1年半放置したExpo製アプリを最新化してみた
wheatandcat
0
100
作成中のFlutterアプリの中間発表
wheatandcat
0
83
最近読んだ技術書を簡単紹介
wheatandcat
0
110
ユニバーサルリンク/アプリリンクを使ってQRコードでゲストログインできるようにする
wheatandcat
0
380
Firebase App Checkを実装したので紹介
wheatandcat
0
310
PlanetScaleの無料プランがなくなるので、NeonとTiDBを試してみた
wheatandcat
0
410
T3 Stack(応用編: Next Auth & SSRの実装紹介)
wheatandcat
1
400
App Routerの紹介
wheatandcat
0
150
Flutter × GraphQLでアプリを作ってみる
wheatandcat
0
340
Featured
See All Featured
Building Applications with DynamoDB
mza
96
7.1k
My Coaching Mixtape
mlcsv
0
150
KATA
mclloyd
PRO
35
15k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
210
Claude Code のすすめ
schroneko
67
230k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
620
GitHub's CSS Performance
jonrohan
1033
470k
Fireside Chat
paigeccino
42
4k
Darren the Foodie - Storyboard
khoart
PRO
3
3.4k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
450
We Have a Design System, Now What?
morganepeng
55
8.2k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Transcript
Flutter HooksとRiverpodの解説 Press Space for next page
自己紹介 📝 飯野陽平(wheatandcat) 🏢 会社: 合同会社UNICORN 代表社員 📚 Blog: https://www.wheatandcat.me/
🛠 今までに作ったもの memoir OOMAKA MarkyLinky
Flutterとは Google開発のオープンソースのマルチプラットフォームの開発フレームワーク 一つのコードベースから、iOS、Android、Web、Windows、Mac、Linuxアプリなど複数のプラットフォ ームの作成が可能 言語はDartを使用 Google独自のUI Widgetを使用(Material Designベース)
Flutter Hooksとは React HooksのFlutter版 flutter_hooks コンポーネントの状態を管理するためのライブラリ Flutter標準のStateful Widgetのコードを簡潔に書くことができる
StatefulWidgetの例 ①. StatefulWidget継承したクラスを宣言 ②. Stateクラスを宣言 ③. Stateの初期化 ④. Stateの更新 ⑤.
Stateの参照 class Count extends StatefulWidget { @override State<Count> createState() => _CountState(); } class _CountState extends State<Count> { int _counter = 0; @override Widget build(BuildContext context) { return TextButton( onPressed: () => { setState(() { _counter++; }), }, child: Text('Increment: $_counter'), ); } }
StatefulWidgetの例 ①. StatefulWidget継承したクラスを宣言 ②. Stateクラスを宣言 ③. Stateの初期化 ④. Stateの更新 ⑤.
Stateの参照 class Count extends StatefulWidget { @override State<Count> createState() => _CountState(); } class _CountState extends State<Count> { int _counter = 0; @override Widget build(BuildContext context) { return TextButton( onPressed: () => { setState(() { _counter++; }), }, child: Text('Increment: $_counter'), ); } }
StatefulWidgetの例 ①. StatefulWidget継承したクラスを宣言 ②. Stateクラスを宣言 ③. Stateの初期化 ④. Stateの更新 ⑤.
Stateの参照 class _CountState extends State<Count> { int _counter = 0; @override Widget build(BuildContext context) { return TextButton( onPressed: () => { setState(() { _counter++; }), }, child: Text('Increment: $_counter'), ); } } class Count extends StatefulWidget { @override State<Count> createState() => _CountState(); }
StatefulWidgetの例 ①. StatefulWidget継承したクラスを宣言 ②. Stateクラスを宣言 ③. Stateの初期化 ④. Stateの更新 ⑤.
Stateの参照 int _counter = 0; class Count extends StatefulWidget { @override State<Count> createState() => _CountState(); } class _CountState extends State<Count> { @override Widget build(BuildContext context) { return TextButton( onPressed: () => { setState(() { _counter++; }), }, child: Text('Increment: $_counter'), ); } }
StatefulWidgetの例 ①. StatefulWidget継承したクラスを宣言 ②. Stateクラスを宣言 ③. Stateの初期化 ④. Stateの更新 ⑤.
Stateの参照 onPressed: () => { setState(() { _counter++; }), }, class Count extends StatefulWidget { @override State<Count> createState() => _CountState(); } class _CountState extends State<Count> { int _counter = 0; @override Widget build(BuildContext context) { return TextButton( child: Text('Increment: $_counter'), ); } }
StatefulWidgetの例 ①. StatefulWidget継承したクラスを宣言 ②. Stateクラスを宣言 ③. Stateの初期化 ④. Stateの更新 ⑤.
Stateの参照 child: Text('Increment: $_counter'), class Count extends StatefulWidget { @override State<Count> createState() => _CountState(); } class _CountState extends State<Count> { int _counter = 0; @override Widget build(BuildContext context) { return TextButton( onPressed: () => { setState(() { _counter++; }), }, ); } }
Flutter Hooksの例 ①. HookWidgetを継承したクラスを宣言 ②. Stateの初期化 ③. Stateの更新 ④. Stateの参照
class Count extends HookWidget { @override Widget build(BuildContext context) { final count = useState(0); return TextButton( onPressed: () => count.value++, child: Text('Increment: ${count.value}'), ); } }
Flutter Hooksの例 ①. HookWidgetを継承したクラスを宣言 ②. Stateの初期化 ③. Stateの更新 ④. Stateの参照
final count = useState(0); class Count extends HookWidget { @override Widget build(BuildContext context) { return TextButton( onPressed: () => count.value++, child: Text('Increment: ${count.value}'), ); } }
Flutter Hooksの例 ①. HookWidgetを継承したクラスを宣言 ②. Stateの初期化 ③. Stateの更新 ④. Stateの参照
onPressed: () => count.value++, class Count extends HookWidget { @override Widget build(BuildContext context) { final count = useState(0); return TextButton( child: Text('Increment: ${count.value}'), ); } }
Flutter Hooksの例 ①. HookWidgetを継承したクラスを宣言 ②. Stateの初期化 ③. Stateの更新 ④. Stateの参照
child: Text('Increment: ${count.value}'), class Count extends HookWidget { @override Widget build(BuildContext context) { final count = useState(0); return TextButton( onPressed: () => count.value++, ); } }
useEffectの解説 Widgetのライフサイクルで処理をさせたい時にuseEffectを使ってみる 生成時、破棄時、更新時 概念的にはReactのuseEffectと同じ
useEffectの例 final id = useState<int>(0); useEffect(() { // ①. id
が変更されたら実行 getItems(id.value); }, [id.value]); useEffect(() { // ②. 初回のみ実行 debugPrint(' 初回のみ実行'); }, const []); useEffect(() { // ③. 破棄時に実行 return () => { debugPrint(' 破棄時に実行'); }; }, [id.value]);
useEffectの例 useEffect(() { // ①. id が変更されたら実行 getItems(id.value); }, [id.value]);
final id = useState<int>(0); useEffect(() { // ②. 初回のみ実行 debugPrint(' 初回のみ実行'); }, const []); useEffect(() { // ③. 破棄時に実行 return () => { debugPrint(' 破棄時に実行'); }; }, [id.value]);
useEffectの例 // ②. 初回のみ実行 debugPrint(' 初回のみ実行'); }, const []); final
id = useState<int>(0); useEffect(() { // ①. id が変更されたら実行 getItems(id.value); }, [id.value]); useEffect(() { useEffect(() { // ③. 破棄時に実行 return () => { debugPrint(' 破棄時に実行'); }; }, [id.value]);
useEffectの例 useEffect(() { // ③. 破棄時に実行 return () => {
debugPrint(' 破棄時に実行'); }; }, [id.value]); final id = useState<int>(0); useEffect(() { // ①. id が変更されたら実行 getItems(id.value); }, [id.value]); useEffect(() { // ②. 初回のみ実行 debugPrint(' 初回のみ実行'); }, const []);
Custom Hookの例 コード量が多くなってくると状態管理とViewのコードを分割したくなる その時にCustom Hookを使うと便利 コードの例は以下を参照 コードのURL 差分は以下の通り 差分のURL
Riverpodとは Riverpod グローバルな状態管理をしたい時に使うライブラリ ReactでいうところのContext APIのようなもの
Riverpodの例 ①. Providerを宣言 ②. Providerを取得 ③. Providerの値を参照 ④. Providerの値を更新 Demo用のURL
▪ lib/providers/counter.dart ▪ lib/main.dart final countProvider = StateProvider((ref) => 0); class HomePage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(countProvider); return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('$count'), FloatingActionButton( onPressed: () => ref.read(countProvider.notif child: Icon(Icons.add), ), ], ), ); } }
Riverpodの例 ①. Providerを宣言 ②. Providerを取得 ③. Providerの値を参照 ④. Providerの値を更新 Demo用のURL
▪ lib/providers/counter.dart ▪ lib/main.dart final countProvider = StateProvider((ref) => 0); final count = ref.watch(countProvider); class HomePage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('$count'), FloatingActionButton( onPressed: () => ref.read(countProvider.notif child: Icon(Icons.add), ), ], ), ); } }
Riverpodの例 ①. Providerを宣言 ②. Providerを取得 ③. Providerの値を参照 ④. Providerの値を更新 Demo用のURL
▪ lib/providers/counter.dart ▪ lib/main.dart final countProvider = StateProvider((ref) => 0); Text('$count'), class HomePage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(countProvider); return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ FloatingActionButton( onPressed: () => ref.read(countProvider.notif child: Icon(Icons.add), ), ], ), ); } }
Riverpodの例 ①. Providerを宣言 ②. Providerを取得 ③. Providerの値を参照 ④. Providerの値を更新 Demo用のURL
▪ lib/providers/counter.dart ▪ lib/main.dart final countProvider = StateProvider((ref) => 0); onPressed: () => ref.read(countProvider.notif class HomePage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(countProvider); return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('$count'), FloatingActionButton( child: Icon(Icons.add), ), ], ), ); } }
まとめ Flutterの状態管理でFlutter HooksとRiverpodを触ってみたが、思っていた以上にReactと同じ方式だったので、Reactの知 識があればすぐに使える Flutterがクラスベースで作成されている言語なのに、Hooksが関数ベースで作成されているのが、若干ちぐはぐな感じはして いる ただ、riverpod_generatorのようなRiverpodの宣言自体を自動生成できる部分はReactよりも進んでいるかも Providerの宣言の種類が多すぎるのでコード生成すると楽 各Providerの役割と使い分け|Flutter x
Riverpod でアプリ開発!実践入門
ご清聴ありがとうございました 🎉