Created
July 31, 2023 02:08
-
-
Save chooyan-eng/c22f48350ef6c2d878a0d893218d816f to your computer and use it in GitHub Desktop.
副作用をフィールドに持つ Notifier と StateNotifier の扱い方の違いのサンプルコード
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:hooks_riverpod/hooks_riverpod.dart'; | |
void main() { | |
runApp(const ProviderScope(child: MaterialApp(home: CounterPage()))); | |
} | |
class CounterPage extends ConsumerWidget { | |
const CounterPage({super.key}); | |
@override | |
Widget build(BuildContext context, WidgetRef ref) { | |
final state = ref.watch(decoratedCounterProvider); | |
// final state = ref.watch(decoratedCounterStateProvider); | |
return Scaffold( | |
body: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text(state, style: const TextStyle(fontSize: 32)), | |
const SizedBox(height: 32, width: double.infinity), | |
ElevatedButton( | |
onPressed: () { | |
ref.read(decoratedCounterProvider.notifier).addDecoration(); | |
// ref.read(decoratedCounterStateProvider.notifier).addDecoration(); | |
}, | |
child: const Text('DECORATE MORE'), | |
), | |
], | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: () { | |
ref.read(counterProvider.notifier).update((state) => state + 1); | |
}, | |
), | |
); | |
} | |
} | |
// カウントを保持する Provider | |
final counterProvider = StateProvider((ref) => 0); | |
// ① Notifier を使って装飾したカウント文字列を保持する例 | |
final decoratedCounterProvider = | |
NotifierProvider<CounterDecorationNotifier, String>(() { | |
return CounterDecorationNotifier(); | |
}); | |
class CounterDecorationNotifier extends Notifier<String> { | |
var _decoration = '*'; // 装飾(Notifier が保持する何かしらの副作用) | |
// watch 先(つまり counterProvider)が変化した際はここが呼び出し直される。 | |
// CounterDecorationNotifier オブジェクトはそのままのため _decoration は保持される。 | |
@override | |
build() { | |
final value = ref.watch(counterProvider); | |
return '$_decoration $value $_decoration'; | |
} | |
// 呼び出しによって何かしらの副作用が発生する処理 | |
void addDecoration() => _decoration = '$_decoration*'; | |
} | |
// ② StateNotifier を使って装飾したカウント文字列を保持する例 | |
final decoratedCounterStateProvider = | |
StateNotifierProvider<CounterDecorationStateNotifier, String>((ref) { | |
// watch 先(つまり counterProvider)が変化した際はここが呼び出し直され、 | |
// CounterDecorationStateNotifier 自体が再生成されるため、 _decoration も初期化される。 | |
return CounterDecorationStateNotifier(ref); | |
}); | |
class CounterDecorationStateNotifier extends StateNotifier<String> { | |
CounterDecorationStateNotifier(this._ref) : super('') { | |
init(); | |
} | |
final Ref _ref; | |
var _decoration = '*'; | |
init() { | |
final value = _ref.watch(counterProvider); | |
state = '$_decoration $value $_decoration'; | |
} | |
void addDecoration() => _decoration = '$_decoration*'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment