[Flutter] Riverpod autoDispose로 자동 해제시켜주기
React를 주로 개발하는 저에게 dispose란 단어는 조금 생소했습니다. 공식적인 단어의 뜻은 처리하다, 처분하다, 폐기하다 로 나타나고 개발쪽에서는 구독 해제, 메모리에서 리소스 해제 정도인 것 같네요. 아무래도 앱개발에서 메모리 관리가 중요하다보니 잘 알아둬야하는 키워드 같습니다.
riverpod으로 상태관리를 하다보면 적절한 시점에 프로바이더를 dispose 해줘야 합니다. 주로 다음과 같은 상황에서 자주 사용됩니다.
- 회원가입 혹은 폼 입력 화면에서 되돌아왔을 때, 입력 폼이 초기화되어있어야함 (임시저장기능이 없다고 가정할 때)
- firebase 혹은 auth를 관리하는 상황에서 로그아웃 시 연결 해제
- 앱의 메모리 절약
1번의 상황이 제가 Flutter로 개발하다 맞닥뜨린 이슈였습니다. 적절히 폼을 초기화 혹은 프로바이더를 dispose하지 않아 다른 화면에서 되돌아왔음에도 상태가 남아있던 상황이었죠. 아래에서 예시 화면과 함께 살펴보겠습니다.
dispose 혹은 초기화를 해주지 않을때
아래 화면은 제가 개발하고 있는 테니스 다이어리앱 입니다. StateNotifierProvider를 활용해 MVVM을 구현하여 상태관리를 하고 있는데 얘기지 못한 이슈가 발생했습니다. 다이어리 생성 중 이전화면으로 되돌아 올시 초기화가 되지 않는 문제였죠.
화면에서 벗어날 시 적절히 provider를 dispose해주지 않아 발생한 이슈입니다. 이는 유저에게 의도하지 않은 사용자 경험을 제공할 수 있고 개발입장에서도 잠재적으로 사이드 이펙트가 생길 수 있습니다. 사용하지 않는 프로바이더가 불필요하게 메모리를 점유 할 수도 있죠.
autoDispose
riverpod에서는 자동으로 dispose해주는 autoDispose를 지원해주고 있습니다. 사용법은 간단하게 provider 선언시에 autoDispose를 뒤에 붙여주기만 하면 됩니다.
final diaryCreateViewModelProvider = StateNotifierProvider.autoDispose<DiaryCreateNotifier, DiaryCreateViewModelState>((ref) {
return DiaryCreateNotifier(ref);
});
이제 다이어리 생성중에 화면에 재 진입해도 이전 상태값들이 초기화됨을 확인할 수 있습니다. 화면에서 벗어나 사용하지 않는 프로바이더 또한 자동으로 해제할 수 있습니다.
ref.keepAlive
프로바이더에 autoDispose를 활성화하면 keepAlive 옵션을 사용할 수 있습니다. 만약 특정 api를 사용하는 프로바이더라면 특정 상황에서는 캐싱이 필요할 수 있습니다. 카테고리와 같이 실시간으로 변하지 않는 값들을 예로 들 수 있겠네요.
다음과 같이 keepAlive 옵션을 활성화 하면 사용자가 페이지를 나갔다가 다시 돌아왔을 때 요청(실행)이 다시 실행되지 않도록 할 수 있습니다.
final myProvider = FutureProvider.autoDispose((ref) async {
final response = await httpClient.get(...);
ref.keepAlive();
return response;
});
마치며
Riverpod에서 제공하는 autoDispose는 편리하지만, 상황에 맞게 신중히 사용하는 것이 중요하다는 것을 느꼈습니다. 특히, API와 연동된 경우 매번 dispose를 하면 서버에 부담이 갈 수 있으니, 적절하게 활용하는 것이 필요하겠네요.