Provider(상태 관리)

Stupefyee's avatar
Dec 30, 2024
Provider(상태 관리)

1. 의존성 주입


2. Provider

1. 코드

main.dar
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'home_page.dart'; void main() { // ref를 쓸려면 이렇게 적어야함 >> 문법 runApp(ProviderScope(child: MyApp())); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } }
home_page.dart
import 'package:flutter/material.dart'; import 'home_body.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { print("Home Page build.."); // HomeBody를 분리해서 HomeBody만 build 되도록 함 return Scaffold( body: HomeBody(), ); } }
home_body.dart
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'home_page_vm.dart'; class HomeBody extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { // ref를 통해 Provider에 접근가능 // Provider의 VM을 생성시키는 메서드 >> state 값을 가져옴 int count = ref.watch(countProvider); // 연결을 한 뒤 유지 //int count = ref.read(countProvider); // 연결을 한 뒤 끊음 CountVM vm = ref.read(countProvider.notifier); // 상태값 변경을 위한 vm을 가져옴 print("Home Body build.."); return Center( child: Column( children: [ OutlinedButton( onPressed: () { vm.add(); }, child: Text("증가")), Text("$count", style: TextStyle(fontSize: 50)), ], )); } }
home_page_vm
import 'package:flutter_riverpod/flutter_riverpod.dart'; // 창고 관리자 final countProvider = NotifierProvider<CountVM, int>(() { print("창고 생성"); return CountVM(); }); // 창고 class CountVM extends Notifier<int> { @override int build() { return 20; } // 행위 void add() { state = state + 1; } }

2. 주요 개념

  1. NotifierProvider
      • 상태와 상태 변경 로직을 포함하는 "창고 관리자" 역할.
      • 데이터를 관리하고 제공하며, 상태 변경 시 알림.
  1. Notifier
      • 상태 값(state)과 상태 변경 메서드를 포함한 "창고".
      • 사용자가 정의한 상태 관리 클래스에 상속하여 구현.
  1. ConsumerWidget
      • Provider에서 제공하는 데이터를 읽고 UI에 반영.
  1. ProviderScope
      • Provider의 상태를 앱 전체에서 사용할 수 있도록 설정.

3. 코드 설명

💡
notion image
1. 창고 관리자와 창고 정의
  • 창고 관리자
    • final countProvider = NotifierProvider<CountVM, int>(() { print("창고 생성"); return CountVM(); });
    • NotifierProviderCountVM 클래스를 통해 상태(정수)를 관리.
    • 앱 전역에서 접근 가능한 countProvider 생성.
  • 창고 (CountVM)
    • class CountVM extends Notifier<int> { @override int build() { return 20; } void add() { state = state + 1; } }
    • Notifier를 상속받아 초기 상태 20을 설정.
    • add 메서드로 상태 값 증가 기능 추가.

2. 화면 구성

  • 메인 진입점
    • void main() { runApp(ProviderScope(child: MyApp())); }
    • ProviderScope로 Riverpod 상태 관리 활성화.
  • HomePage
    • class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { print("Home Page build.."); return Scaffold( body: HomeBody(), ); } }
    • UI를 HomeBody로 분리하여 상태 변경 시 효율적으로 재빌드.
  • HomeBody
    • class HomeBody extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { int count = ref.watch(countProvider); CountVM vm = ref.read(countProvider.notifier); print("Home Body build.."); return Center( child: Column( children: [ OutlinedButton( onPressed: () { vm.add(); }, child: Text("증가")), Text("$count", style: TextStyle(fontSize: 50)), ], )); } }
    • ref.watch(countProvider): countProvider의 상태 값을 지속적으로 구독.
    • ref.read(countProvider.notifier): 상태 변경을 위한 CountVM 접근.
    • 버튼 클릭 시 vm.add()로 상태를 업데이트하고 UI를 재빌드.
Share article

stupefyee