[플러터] 15. Riverpod로 상태 관리

KangHo Lee's avatar
Dec 30, 2024
[플러터] 15. Riverpod로 상태 관리

1. Flutter_Riverpod 라이브러리 세팅

💡
  • Flutter 앱에서 상태 관리와 관련된 강력하고 유연한 라이브러리입니다.
  • 상태 관리 기능만 담아서 Flutter 업데이트 반영이 빠릅니다.
  • 라이브러리 추가
    • riverpod 아니고 flutter_riverpod을 설치해야 합니다.
    • 터미널에서 flutter pub add flutter_riverpod 실행
  • 플러그인 설치
    • 안드로이드 스튜디오 → Settings → Plugins
    • Flutter Riverpod Snippet 추가
  • 라이브 템플릿(스니펫) 추가
// fno 자동 완성 import 'package:flutter_riverpod/flutter_riverpod.dart'; final xxProvider = NotifierProvider<$NAME$VM, int>(() { return $NAME$VM(); }); class $NAME$VM extends Notifier<int> { @override int build() { return 0; } }

2. 코드

main.dart

import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverapp/home_page.dart'; void main() { runApp(ProviderScope(child: MyApp())); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } }
  • runApp(ProviderScope(child: MyApp()))
    • provider를 인식하기 위한 scope 설정

home_page.dart

import 'package:flutter/material.dart'; import 'package:riverapp/home_body.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { print("HomePage build..."); return Scaffold( body: HomeBody(), ); } }
  • 상태 변경 시 Scaffold가 리빌드되지 않도록 body 내용을 분리

home_body.dart

import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:riverapp/home_page_vm.dart'; class HomeBody extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { print("HomeBody build..."); // watch나 read 둘 중 하나는 실행 되어야 구독 int count = ref.watch(countProvider); // 상태 변경 바로 반영 // int count = ref.read(countProvider); // 상태 변경 반영 x, 상태는 변경 중 CountVM vm = ref.read(countProvider.notifier); return Center( child: Column( children: [ OutlinedButton( onPressed: () { // 상태 변경 vm.add(); }, child: Text("증가")), Text( // 상태 "$count", style: TextStyle(fontSize: 50), ), ], ), ); } }
  • ConsumerWidget을 상속 받아 Riverpod 상태를 구독할 수 있습니다.
    • WidgetRef ← ref
      • ConsumerWidget 상속 시 build()의 매개변수에 추가해야 합니다.
      • provider에 접근할 수 있는 클래스입니다.
  • int count = ref.watch(countProvider)
    • countProvider를 읽어서 현재 상태 값을 가져옵니다.
    • watch의 경우 연결을 유지하면서 상태값이 바뀔 때 마다 view의 값을 갱신해줍니다.
    • read의 경우 최초의 상태값을 설정하고 연결을 끊습니다.
      • 상태가 변경되어도 view의 값이 갱신되지 않습니다.
  • CountVM vm = ref.read(countProvider.notifier);
    • countProvider의 ViewModel (CountVM)을 가져옵니다.
    • CountVM의 메서드를 통해 상태를 변경시킬 수 있습니다. (write 같은 느낌)
💡
구독하는 메서드
  1. VM = ref.watch( Provider ); → 상태 변화 주시 중
  1. VM = ref.read( Provider ); → read only
  1. VM = ref.read( Provider.notifier ); → write, 상태 변경

home_page_vm.dart (CountVM)

import 'package:flutter_riverpod/flutter_riverpod.dart'; final countProvider = NotifierProvider<CountVM, int>(() { print("ViewModel 생성"); return CountVM(); }); // ViewModel class CountVM extends Notifier<int> { @override int build() { return 20; // 초기 상태값 } // 상태를 변경하는 행위 void add() { state = state + 1; print("값바뀜 : $state"); } }
  • countProvider
    • NotifierProvider를 사용하여 CountVM을 상태 관리자(Notifier)로 등록합니다.
    • NotifierProvider<ViewModel 이름 , 관리할 상태의 타입 >
      • 타입은 List같은 컬렉션 등 다양하게 선택할 수 있습니다.
    • () { return CountVM() }이라는 익명 함수를 매개 변수로 받고 있습니다.
💡
  • Dart 문법의 특성 때문에 익명 함수를 실행시키지 않습니다.
  • 함수 자체를 매개 변수로 받아서 넘겨줍니다.
  • WidgetRef.watch나 read로 호출을 해야 CountVM(ViewModel)을 생성해서 return합니다.
  • CountVM(ViewModel 클래스)
    • Notifier<int>를 상속받아 상태를 관리합니다.
    • build
      • 초기 상태값을 반환합니다.
    • add
      • 개발자가 작성한 상태를 변경하는 메서드입니다.
💡
상태를 가리키는 변수 이름은 state입니다.
 
Share article

devleekangho