[Flutter] 상태관리 - Provider

송상민·2022년 10월 6일
0

Flutter

목록 보기
5/13
post-thumbnail

Provider를 이용해 상태관리 하는법을 알아보자.

Provider

Provider는 App State를 관리하기 위해 Flutter에서 제공하는 라이브러리다. Provider 외에도 사용할 수 있는 방법은 많이 존재한다. 대표적으로 많이 쓰이기에 가장 먼저 정리해보려 한다.

Provider 요소

Provider에 많은 요소들 중 4가지 요소만 살펴보려한다.

1. ChangeNotifier
2. ChangeNotifierProvider
3. Consumer
4. Provider.of

먼저 Provider를 사용하기 위해서는 pubspec.yaml에 의존성을 추가해야한다.

dependencies:
	flutter:
    	sdk: flutter
    provider: ^<latest vesion>
    
dev_dependencies: 

1.ChangeNotifier

변경사항을 알릴 수 있는 클래스. notifyListener()를 사용하면 ChangeNotifier를 구독하고 있는 Listener에게 변경사항이 전달된다. 아래는 이해를 돕기 위한 에제이다.

class CounterProvider with ChangeNotifier, DiagnosticableTreeMixin {
  int _count = 0;

  int get count => _count;

  void increment() { //증가 함수
    _count++;
    notifyListeners(); //이 함수를 통해 화면 상태 변경을 리스너에게 전달한다.
  }

  
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    // TODO: implement debugFillProperties
    super.debugFillProperties(properties);
    properties.add(IntProperty('count', count)); //property 제공을 위한 count add
  }
}

추가적으로 ChangeNotifier는 flutter:foundation에 존재하고 고수준 클래스(ex: Widget, etc)에 의존성이 없어서 테스트하기가 쉽다.

2.ChangeNotifierProvider

ChangeNotifierProvider는 ChangeNotifier를 하위 항목에 제공하는 위젯이다. 아까전에 notifyLisner를 통해 ChangeNotifier를 구독하고 있는 Listner에게 변경사항이 전달된다고 했는데, ChangeNotifierProvider는 하위 항목들에게 ChangeNotifier를 제공하여 구독할 수 있도록 해준다. 아래는 ChangeNotifierProvider를 선언하는 예제이다.

void main() {
  runApp(
      ChangeNotifierProvider(
      create: (_) => CounterProvider()), // Provider를 사용하기 위한 Provider선언
    child: const MyApp(),
    ),
  );
}

ChangeNotifierProvider는 똑똑해서 CounterProvider의 Instance를 잘 관리해준다. CounterProvider의 Instance를 굳이 다시 rebuild 할 필요가 없고, dispose()도 적절한 시점에 자동으로 호출한다.
Provider를 여러개 선언하고 싶을 때는 MultiProvider를 사용하면 된다. 아래는 예제이다.

void main() {
  runApp(
    MultiProvider(providers: [ //Provider를 여러개 사용시 MultiProvider
      ChangeNotifierProvider(create: (_) => CounterProvider()), // Provider를 사용하기 위한 Provider선언
    ],
    child: const MyApp(),
    ),
  );
}

3.Consumer

Consumer는 ChangeNotifierProvider에서 하위 항목에서 ChangeNotifier에 접근할 수 있게 한다.

return HumongousWidget(
  child: AnotherMonstrousWidget(
    child: Consumer<CounterProvider>(
      builder: (context, countmodel, child){
       	return Text('${countmodel.count}');
      },
    ),
  ),
),

지정한 ChangeNotifier의 이름인 CounterProvider를 Consumer<>안에 넣어준다. Consumer 위젯의 필수 인자인 builder 함수는 3가지 인수로 작동된다.

  • context: 모든 build 함수는 context를 가진다.
  • ChangeNotifier: 우리가 정의한 ChangeNotifier인 CounterProvider이다. ChangeNotifier의 데이터를 통해 우리가 원하는 Widget을 작성할 수 있다.
  • child: 이름 그대로 가지고 있던 서브트리 위젯이다. 이를 이용해 다시 서브트리를 작성하지 않고 재활용할 수 있다.

4.Provider.of

Provider.of도 Consumer와 같이 ChangeNotifier를 구독하고 있는 Listener이다. Consumer와 다른 점은 Provider.of는 위젯이 아니라 ChangeNotifier 그 자체를 반환한다. 아래는 예제이다.

class Count extends StatelessWidget { // Count 개수를 표한하는 부분을 필요없는 rebuild를 없애기 위해 따로 위젯화
  const Count({Key? key}) : super(key: key);
  
  var counts = Provider.of<CounterProvider>(context); //CounterProvider를 반환하기 위한 Provider.of 사용

  
  Widget build(BuildContext context) {
    return Text(
        counts.count, //CounterProvider 안에 있는 count 상태 읽어오기.
        key: const Key('counterState'),
    );
  }
}

만약 ChangeNotifier에서 notifyListener()가 호출되면 해당 StatelessWidget의 build()가 다시 호출됩니다. 만약 StatefulWidget이라면 State.didChangeDependencies가 호출된다.


Provider에 대하여 더 궁금한 부분은 아래 공식문서를 읽어보자.
Provider Flutter 공식문서 (API docs)

profile
실력있는 Flutter 개발자가 되어보자

0개의 댓글