본문으로 건너뛰기

ProviderObserver

ProviderObserver는 ProviderContainer의 변화를 관찰합니다.

ProviderObserver를 사용하기 위해서, 사용하고자 하는 클래스에 ProviderObserver를 상속하고 메소드를 오버라이드(override)하여 사용할 수 있습니다.

ProviderObserver는 3개의 메소드를 가집니다.

  • didAddProvider: 프로바이더(provider)가 초기화 될때 마다 호출됩니다. 노출되는 값은 값(value)입니다.
  • didDisposeProvider: 프로바이더(provider)가 disposed될 때마다 호출됩니다.
  • didUpdateProvider: 프로바이더(provider)값이 변경(when they emit a notification)될 때 마다 호출됩니다.

사용법:

ProviderObserverdidUpdateProvider를 오버라이딩 하여 프로바이더들(providers)의 변화를 로깅할 수 있습니다.


// riverpod과 Logger를 사용한 카운터 앱 예제

class Logger extends ProviderObserver {

void didUpdateProvider(
ProviderBase<Object?> provider,
Object? previousValue,
Object? newValue,
ProviderContainer container,
) {
print('''
{
"provider": "${provider.name ?? provider.runtimeType}",
"newValue": "$newValue"
}''');
}
}

void main() {
runApp(
// ProviderScope를 추가하여 프로젝트 전반적으로 Riverpod을 사용가능하도록 합니다.
// observers 리스트(목록)에 위에서 정의한 Logger 클래스를 추가합니다.
ProviderScope(observers: [Logger()], child: const MyApp()),
);
}

class MyApp extends StatelessWidget {
const MyApp({super.key});


Widget build(BuildContext context) {
return MaterialApp(home: Home());
}
}

final counterProvider = StateProvider((ref) => 0, name: 'counter');

class Home extends ConsumerWidget {

Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);

return Scaffold(
appBar: AppBar(title: const Text('Counter example')),
body: Center(
child: Text('$count'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: const Icon(Icons.add),
),
);
}
}

이제 프로바이더 상태 값이 갱신될때 마다 로거에 기록으로 출력될 것입니다.

I/flutter (16783): {
I/flutter (16783): "provider": "counter",
I/flutter (16783): "newValue": "1"
I/flutter (16783): }