Flutter 앱에서 Riverpod으로 상태 관리 전환한 후기
배경
사내 모바일 앱을 Flutter로 개발하면서 Provider를 사용해왔다. 그런데 앱이 복잡해지면서 BuildContext 의존성과 런타임 에러가 자주 발생했다. 특히 ProviderNotFoundException은 디버깅이 까다로웠다.
Riverpod이 Provider의 문제를 해결한다는 글을 보고 도입을 결정했다.
Riverpod의 장점
1. BuildContext 불필요
// Provider
final counter = Provider.of<Counter>(context);
// Riverpod
final counter = ref.watch(counterProvider);
Context 없이도 provider 접근이 가능해 위젯 트리 구조에서 자유로워졌다.
2. 컴파일 타임 안정성
final userProvider = FutureProvider<User>((ref) async {
final api = ref.watch(apiProvider);
return api.fetchUser();
});
타입 추론이 잘 되고, 잘못된 provider 호출은 컴파일 단계에서 잡힌다.
3. 테스트 편의성
test('counter increments', () {
final container = ProviderContainer(
overrides: [
counterProvider.overrideWithValue(Counter(10)),
],
);
expect(container.read(counterProvider).value, 10);
});
WidgetTester 없이도 로직 테스트가 가능해졌다.
마이그레이션 과정
점진적으로 마이그레이션하기 위해 ProviderScope를 앱 루트에 추가하고, 새로운 기능부터 Riverpod으로 작성했다. Provider와 Riverpod은 공존 가능해서 부담이 적었다.
가장 까다로웠던 부분은 ChangeNotifierProvider 대체였다. StateNotifierProvider로 변환하면서 불필요한 rebuild가 줄어드는 효과도 있었다.
결론
2주 정도 걸려 핵심 기능을 Riverpod으로 전환했다. 코드가 간결해지고 테스트 커버리지도 올라갔다. Flutter 2.0이 나오기 전에 미리 전환해둔 것이 다행이라고 생각한다.