MVVM — RiverPod

Eungae's avatar
Jan 08, 2026
MVVM  — RiverPod

MVVM이란

  • Model + View + ViewModel 의 약자
  • Model : 데이터를 서버 등에서 가지고 오는 계층
    • JSON 예제에서 Human, Pet 클래스 — JSON에서 데이터를 가지고 오는 클래스
    • 서버에서 데이터를 가지고 오는 경우에는 각 모델(데이터 클래스)별로 Repository를 만들어서 가지고와서 JSON을 객체로 변환해서 반환
  • View : 화면을 구현하는 계층
    • 위젯
  • ViewModel : Model 계층(Repository)에서 데이터(Model 클래스)를 가지고 와서 가공 및 상태 관리하는 계층
 

MVVM과 StatefulWidget 비교

StatefulWidget

사용자 클릭, 로직 처리
→ 데이터 요청해서 데이터 받음
→ 받은 데이터 가공 및 상태 업데이트
→ 화면 업데이트
⇒ StatefulWidget에서 많은 역할 수행 == 코드 지저분해짐.
 

MVVM 작동 원리

ViewModel 관찰 시작 (ViewModel의 상태가 변하는지 안 변하는지)
→ 사용자 클릭 = ViewModel에 처리 요청
→ 로직 처리
→ 데이터 요청해서 데이터 받음
→ 받은 데이터 가공 및 상태 업데이트
→ 자신의 상태가 바뀌었다고 알림 (View가 누군지는 모름)
→ View는 ViewModel을 구독하고 있기 때문에 상태가 바뀌었다는 것을 감지. 화면 업데이트.
 
얻게 되는 효과
  • 각각 계층의 역할에 맞게 코드를 작성하기 때문에 코드가 깔끔해짐
    • 유지보수 편해짐
    • 오류발생 감소
    • 중복코드 감소
  • 각각 역할이 분리되어 있으니 각자 역할에 맞는 테스트 작성 가능
  • 서로 결합도(View는 ViewModel을 참조하지만 ViewModel은 어떤 View가 참조하는지 모름)이 낮아져서 테스트 작성 용이
 
Flutter에서 MVVM 구현
  • 상태관리 라이브러리 활용 : RiverPod


 
 
 

RiverPod

  • 상태관리 라이브러리
  • ViewModel의 역할 (상태를 관리하고 변경되었음을 알려주는 역할)을 쉽게 구현 가능
  • View(Widget)에서 ViewModel의 관찰을 쉽게 하게 해줌
 

사용법

ViewModel 만드는 법

  • 관리할 데이터를 담을 상태 클래스를 만든다.
    • class HomeState { int counter; HomeState(this.counter); }
  • Notifier를 상속받는 ViewModel class를 만든다.
    • // Notifier를 상속받으면 상태를 저장하고 업데이트할 수 있는 기능을 갖게 됨 (ViewModel의 구실 가능) // Notifier 상속 시 이 ViewModel이 어떤 상태를 관리하는지 제너릭으로 지정 class HomeViewModel extends Notifier<HomeState> { // Notifier 클래스의 build 메서드를 재정의 하여 초기 상태값 return 하기 => HomeViewModel이 생성되면 build 메서드의 리턴값으로 상태가 초기화 @override HomeState build() { return HomeState(1); } void updateState() { // 상태를 업데이트 해줄 땐 새로운 객체를 만들어 변경 state = HomeState(state.counter +1); //새로운 객체를 state에 할당하지 않으면 자신을 바라보는 View에게 상태가 변경되었다고 알리지 않음. // state.counter++; // => X } }
  • ViewModel을 관리 및 공급해 줄 NotifierProvider 객체를 변수에 담아준다.
    • // 뷰에서는 이 공급자에게 ViewModel 달라고 요청. => 뷰모델 관리자 final homeViewModelProvider // 이 뷰모델 관리자가 관리해야할 뷰모델의 타입과 뷰모델이 관리하는 상태 제너릭으로 명시 = NotifierProvider<HomeViewModel, HomeState>( // 생성자에 뷰모델을 생성하는 함수를 넘겨줌 // 뷰에서 관리자에게 뷰모델 달라고 요청할 때 실행되어 뷰모델이 생성됨 // 단 기존에 생성이 되어있으면 기존에 생성된 걸 전달 (){ return HomeViewModel(); });
 
Widget에서 사용법
  • Consumer 위젯 사용
    • Consumer( builder: (context, ref, child){ ref.watch(homeViewModelProvider); return Column(children: [ Text() ]); } )
  • 뷰모델 관리자(공급자)가 뷰모델을 제공할 수 있게 최상위 위젯 ProviderScope로 감싸기
    • void main() { // 이 앱에서 ViewModel을 RiverPod이 관리하게 해줌 runApp(const ProviderScope(child:MyApp())); }
       
Share article

나새끼메이커