Skip to content

Instantly share code, notes, and snippets.

@chooyan-eng
Created July 31, 2023 02:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chooyan-eng/c22f48350ef6c2d878a0d893218d816f to your computer and use it in GitHub Desktop.
Save chooyan-eng/c22f48350ef6c2d878a0d893218d816f to your computer and use it in GitHub Desktop.
副作用をフィールドに持つ Notifier と StateNotifier の扱い方の違いのサンプルコード
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