[Flutter] ProviderObserver

겨레·2024년 7월 24일
post-thumbnail

로깅 용도로 자주 쓰이는 ProviderObserver에 대해 알아보자.


① observers 추가하기
main으로 가서 ProviderScope 안에 observers 추가하기

ProviderScope 안에 Observer라는 걸 집어 넣을 수 있음

📍 observers

Provider들을 관찰할 수 있는 기능을 이 안에 넣을 수 있음


② riverpod/provider_observer.dart 파일 생성

②-1. Logger 클래스 만들기
Logger 기능을 주로 쓰니까 이걸로 예시를 드는 거고, 다른 기능을 사용해도 됨!

②-2. ProviderObserve 상속받기
ProviderObserve를 상속(extends)받아야지 main.dart 안에
observer라는 [ ] 파라미터 안에 넣을 수가 있음!

②-3. Logger 미리 넣어 놓기
main에 Logger 미리 넣어 놓자.

  • main.dart 코드
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_study/riverpod/provider_observer.dart';
import 'package:riverpod_study/screen/home_screen.dart';

void main() {
  runApp(
    ProviderScope(
      observers: [
        Logger(),
      ],
      child: const MaterialApp(
        home: HomeScreen(),
      ),
    ),
  );
}

②-4. 오버라이드 하기
ProviderObserver 안에 오버라이드 할 수 있는 값들이 몇 개 있음.
👉 didUpdateProvider / didAddProvider / didDisposeProvider


📍 1) didUpdateProvider

Provider가 업데이트되면 불리는 함수

class Logger extends ProviderObserver {
  
  void didUpdateProvider(ProviderBase provider, Object? previousValue,
      Object? newValue, ProviderContainer container) {}
}


✔ didUpdateProvider의 파라미터

  • ProviderBase provider → 그냥 Provider로 어떤 Provider와 업데이트가 됐는지.
  • previousValue → 기존 값
  • newValue → 다음 값
  • ProviderContainer container → Provider를 담고있는 컨테이너 같은 거(Flutter 사용 시, 신경 안 써도 됨!!!)

1) didUpdateProvider

이렇게 Logger를 넣으면 ProviderScope 안에 있는...
그러니까 하위에 있는 모든 Provider들이 업데이트 됐을 때,
무조건 didUpdateProvider 코드가 불린다.

print로 확인해보자!

  • provider_observer.dart 코드
import 'package:flutter_riverpod/flutter_riverpod.dart';

class Logger extends ProviderObserver {
  
  void didUpdateProvider(ProviderBase provider, Object? previousValue,
      Object? newValue, ProviderContainer container) {
    // 어떤 액션이 취해졌는지 print 찍어서 확인
    print(
        '[Provider Updated] provider: $provider / pv: $previousValue / nv: $newValue');
  }
}

앱 재실행 후, StateProviderScreen 버튼 누르고 들어가서
UP 버튼을 누르면...
Provider가 업데이트될 때마다 어떤 State는 provider인지,
pv(기존값)이 뭐였고, nv(다음값)이 뭔지 모두 업데이트 받을 수 있는 걸 볼 수 있다.

그런데 Logger를 지금 StateProvider 안에만 적용한 게 아니라
ProviderScope 전체에다가 적용했기 때문에
어떤 Provider가 업데이트되더라도 print 받을 수 있음!



ProviderScreen도 확인해보자~

여기서 체크박스를 누르면... 이렇게 잘 print되어 나온다.


📍 2) didAddProvider

Provider가 추가되면 불리는 함수

class Logger extends ProviderObserver {
  
  void didAddProvider(ProviderBase<Object?> provider, 
	Object? value, ProviderContainer container) {}
} 

2) didAddProvider

코드 추가 후, 재실행하고 각 버튼을 누를 때마다 Added가 찍히는 걸 볼 수 있다.
(Provider에 어떤 것들이 추가됐는지를 볼 수 있음.)


📍 3) didDisposeProvider

Provider가 삭제되면 불리는 함수

class Logger extends ProviderObserver {
  
  void didDisposeProvider(
      ProviderBase<Object?> provider, ProviderContainer container) {}
} 

3) didDisposeProvider

이것도 그럼 확인해보자!

AutoDisposeModifierScreen 버튼을 누르면...

로딩이 되고, 로딩이 될 땐 Provider Added가 찍힘.

그리고 값이 나오자마자 Updated로 불림.

⭐ AutoDispose의 특성
→ Provider가 더 이상 화면에서 필요없어지만 삭제됨!

뒤로가기 버튼을 눌러보자!!!
그러면 ...

Disposed가 불려서 찍히는 걸 볼 수 있다.



이를 통해서 ProviderObserver를 extends 한 무언가를 작성하면,
didUpdateProvider , didAddProvider , didDisposeProvider 이 3가지 메소드를
오버라이드 할 수 있는다.
그리고 이 값들을 가지고 상태(State)들 안에 있는 값들을 모니터링(로깅)할 수 있음!


  • provider_observer.dart 전체 코드
import 'package:flutter_riverpod/flutter_riverpod.dart';

class Logger extends ProviderObserver {
  
  void didUpdateProvider(ProviderBase provider, Object? previousValue,
      Object? newValue, ProviderContainer container) {
    // 어떤 액션이 취해졌는지 print 찍어서 확인
    print(
        '[Provider Updated] provider: $provider / pv: $previousValue / nv: $newValue');
  }

  
  void didAddProvider(ProviderBase<Object?> provider, Object? value,
      ProviderContainer container) {
    print('[Provider Added] provider: $provider / value: $value');
  }

  
  void didDisposeProvider(
      ProviderBase<Object?> provider, ProviderContainer container) {
    print('[Provider Disposed] provider: $provider');
  }
}
profile
호떡 신문지에서 개발자로 환생

0개의 댓글