Flutter에서 ref.invalidate()를 바로 호출하면 생기는 문제와 Future.microtask로 해결한 방법
Flutter로 앱을 개발하면서 Riverpod의 ref.invalidate()를 사용할 일이 생겼다.
푸시 알림을 통해 결과 화면으로 진입했을 때, 바로 서버에서 받아온 데이터를 화면에 띄우고 싶었다. 그래서 페이지에 진입하자마자 리스트를 갱신해주려고 ref.invalidate()를 호출했다.
문제 상황
처음에는 다음과 같은 구조로 간단하게 코드를 작성했다.
@override
Widget build(BuildContext context) {
final listAsync = ref.watch(
listAsync(dataIdentifier: identifier),
);
// 푸시 알림으로 진입하면 리스트를 새로 불러오기 위해 invalidate 호출
ref.invalidate(listProvider(dataIdentifier: identifier));
};
이 코드를 작성하고 실행했을 때는 큰 문제가 없는 것처럼 보였다. 하지만 실제 앱에서 테스트를 반복하다 보니 이상한 현상이 눈에 띄었다. 페이지에 들어가자마자 리스트가 계속 새로고침되고, 로딩 인디케이터가 무한히 반복되었다. 다시 말해, 프로바이더가 계속해서 재빌드되고 있었다.
원인 분석
이 문제는 위젯이 완전히 초기화되기 전에 ref.invalidate()를 호출하면서 생긴다. 이 타이밍에 Riverpod은 해당 Provider를 다시 만들고, 그 과정에서 ref.watch(...)가 또 트리거되어 무한 루프처럼 동작하게 되는 것이다.
결국 invalidate와 watch가 서로 영향을 주며, 화면이 계속 깜빡이는 결과로 이어진다. UI도 불안정해지고, 사용자가 보기에도 이상한 경험이 되어버린다.
✅ 해결 방법: Future.microtask
이럴 때는 Dart의 microtask 큐를 활용해서, 위젯이 다 초기화된 다음에 invalidate를 호출해주는 게 안전하다. 간단하게 Future.microtask로 해결할 수 있다.
@override
void initState() {
super.initState();
Future.microtask(() {
ref.invalidate(listProvider(dataIdentifier: identifier));
ref.read(listProvider(dataIdentifier: identifier).future);
});
}
이렇게 바꾸고 나니, 페이지 진입 시 바로 영상이 잘 뜨고, 더 이상 무한 새로고침도 발생하지 않았다. microtask 덕분에 위젯이 안정된 상태에서 invalidate가 실행되면서 문제를 말끔히 해결할 수 있었다.
정리하며
Riverpod에서 ref.invalidate()나 ref.read()를 사용할 때는 위젯이 초기화된 이후에 실행되도록 타이밍을 조절해주는 것이 중요하다. 너무 이른 시점에 호출하면 Provider가 계속 재빌드되어 앱이 불안정해질 수 있다.
이럴 때 Future.microtask는 정말 유용한 도구가 된다. 한 번 초기화가 끝난 이후에 코드를 실행할 수 있도록 도와주기 때문이다. 이 방식은 Riverpod뿐 아니라 Navigator, setState, context 등을 다룰 때도 굉장히 유용하다.
비슷한 문제를 겪고 있다면, 꼭 한 번 microtask를 시도해보자. 생각보다 간단하게 문제를 해결할 수 있다 :)
'개발 > Android' 카테고리의 다른 글
[Kotlin] Firebase Realtime Database에서 리스트 형태로 데이터 저장 및 조회하는 방법 (0) | 2025.04.23 |
---|---|
[Flutter] 영상 플레이어 — VideoPlayer에서 BetterPlayer로, 그리고 비율 문제 해결 (0) | 2025.04.17 |
[Flutter 오류 해결] Gradle & Java 버전 호환 이슈 해결 방법 (feat. Java 21 → 17 다운그레이드) (1) | 2025.04.17 |
[Flutter] Riverpod 상태관리 - ConsumerStatefulWidget 가이드 (0) | 2025.04.02 |
[Flutter] Riverpod 상태관리 - watch vs read 차이 (0) | 2025.04.02 |