[플러터] 15. RiverPod 개념 정리

백하림's avatar
May 29, 2025
[플러터] 15. RiverPod 개념 정리
Contents
요약

📘 개요

Flutter에서 상태 관리를 할 때 Riverpod을 사용하면 위젯과 상태를 명확히 분리할 수 있다.
이 문서는 Riverpod의 기본 구성과 실행 흐름을 "창고 - 관리자 - 직원" 비유를 통해 이해한다.

✅ 전체 흐름 요약

역할
코드 예시
비유 설명
창고
HomeVM extends Notifier<int>
숫자 상품을 들고 있는 창고
창고 관리자
homeProvider = NotifierProvider(...)
창고의 위치와 관리 정보
직원 (읽기)
ref.watch(homeProvider)
창고의 상품을 감시하는 감시자
직원 (조작)
ref.read(homeProvider.notifier).increase()
창고의 상품을 늘리는 작업자
상품
state
실제 숫자 값 (예: 1, 2, 3...)

🧠 Riverpod 주요 개념 (비유 중심)

개념
설명
비유
ProviderScope
앱 전체에서 Provider를 사용할 수 있게 해주는 컨테이너
시 전체 물류를 총괄하는 시청
Notifier<T>
상태를 직접 갖고 있는 객체, 로직 포함 가능
창고 주인 (상품 보유 + 수량 조절 가능)
NotifierProvider
Notifier를 외부에 제공하고 연결하는 Provider
창고 관리자 (주소표 + 문 열기 역할)
ref.watch()
Provider의 값을 관찰하며 값이 바뀌면 자동으로 리빌드
CCTV로 창고를 계속 지켜보는 느낌
ref.read()
Provider의 현재 값만 한 번 가져옴, 변화 감지는 안 함
택배하러 잠깐 들리는 느낌

🔧 파일별 설명

📂 main.dart

void main() { runApp(const ProviderScope(child: MyApp())); }
  • 앱 전체에 Provider 기능을 활성화하기 위한 필수 코드
  • 비유: 모든 창고 접근이 가능하도록 허가 내리는 "시청"

📂 home_vm.dart (창고 설계)

class HomeVM extends Notifier<int> { @override int build() => 1; void increase() { state++; } } final homeProvider = NotifierProvider<HomeVM, int>(() => HomeVM());
  • 상태(int)를 보관하는 HomeVM이라는 창고 클래스
  • state++로 값을 증가시킬 수 있음
  • 비유: 처음엔 물건 1개. increase() 하면 창고에 물건 더 넣는 느낌

📂 home_page.dart (직원들이 활동하는 화면)

// HeaderPage int count = ref.watch(homeProvider); // 상태 감시
  • 숫자 상태를 감시하는 페이지
  • 값이 변경되면 자동으로 리빌드됨
  • 비유: CCTV로 창고를 감시 → 숫자 변하면 바로 UI 갱신됨
// BottomPage HomeVM vm = ref.read(homeProvider.notifier); vm.increase(); // 상태 변경
  • 버튼 클릭 시 숫자 증가
  • 비유: 직원이 창고에 가서 직접 물건을 추가하는 행동

🔁 실행 흐름 요약

  1. 앱 시작 → ProviderScope로 전체 감싸기
  1. homeProvider를 통해 HomeVM 창고 생성됨
  1. HeaderPageref.watch()로 상태를 감시
  1. BottomPageref.read()increase() 실행
  1. 상태가 변경되면 HeaderPage만 리빌드됨

🧾 실제 UI 레이아웃

Column( children: [ Expanded(child: HeaderPage()), // 상태 표시 Expanded(child: BottomPage()), // 버튼 클릭 시 상태 변경 ], )

🎯 정리 포인트

  • 창고는 Notifier로 만들고, 상태는 state로 직접 다룸
  • 상태 감시용은 ref.watch(), 조작은 ref.read()
  • 위젯을 ConsumerWidget으로 분리하면 리빌드 범위 최소화 가능
  • 구조적으로 읽기 쉬우면서도 성능도 좋아짐

💬 참고 도식 (텍스트형)

[ProviderScope] | [MyApp] | [HomePage] ┌───────────────┐ ┌───────────────┐ │ HeaderPage │◄─────┤ ref.watch() │ │ (숫자 출력) │ │ 상태 변경 감지 │ └───────────────┘ └───────────────┘ ┌───────────────┐ ┌───────────────┐ │ BottomPage │─────►│ ref.read().increase() │ │ (버튼으로 증가)│ └───────────────┘ └───────────────┘

요약

🔥
값은 watch로 감시하고,
값은 read로 실행되는 행위를 통해서 변경된다.
행위는 보통 한 번만 실행되면 되니까 read가 적절하다.
Share article

harimmon