ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • flutter - provider 패턴
    개발 2023. 1. 4. 19:49

     

    flutter의 상태 관리 방법으로 BLOC은 작업을 추가할 때마다 이벤트 클래스를 매번 생성해야하는 번거로움이 있고 코드가 불필요하게 길어져서 가독성이 떨어진다. 뿐만 아니라 MVVM 패턴에 익숙한 사람에게는 BLOC을 활용하는 작업이 직관적으로 받아들여지지 않는다. 다행히도 나만 불편함을 느낀게 아닌지 BLOC을 대체하는 많은 대체할 수 있는 라이브러리가 다수 존재한다. 나는 Provider 패턴이 가장 쓰기 쉬웠다.

     

    라이브러리 추가

     

    dependencies:
      flutter:
        sdk: flutter
      provider: ^6.0.5

     

    먼저 provider 라이브러리를 추가한다. 작성기준 최신 버전은 6.0.5 다.

     

    ChangeNotifier 인스턴스 추가

     

    class ExampleModel with ChangeNotifier {
      int counter = 0;
    
      increaseCount() {
        counter++;
        notifyListeners();
      }
    }

     

    화면 변화를 통제할 책임질 ChangeNotifier 인스턴스를 만들어야 한다. ChangeNotifier 클래스 내부에서 변화가 생기면 구독하고 있는 인스턴스들에게 변화를 알릴 수 있다. 위 코드는 ChangeNotifier를 믹스인해서 만들었다. 클래스 내부의 변수를 외부에 공개할 수 있고 이 변화를 알릴 수 있다. 상태 변경후 notifyListeners() 함수를 호출해야 구독 인스턴스에게 알림이 간다.

     

    void main() {
      runApp(ChangeNotifierProvider(
        create: (_) => ExampleModel(),
        child: Example(),
      ));
    }

     

    ChangeNotifier로 만든 인스턴스를 위젯에게 전달해야한다. Provider 패키지에 포함된 ChangeNotifierProvider 클래스는 위젯에게 ChangeNotifier 인스턴스를 제공할 수 있다. 위젯을 생성하는 부분에 같이 선언한다.

     

    ChangeNotifier 변화 구독

     

    class Example extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            home: Consumer<ExampleModel>(
          child: GestureDetector(
            child: const Text(
              "increase tap",
              style: TextStyle(fontSize: 30),
            ),
            onTap: () {
              context.read<ExampleModel>().increaseCount();
            },
          ),
          builder: (context, model, child) {
            return Column(
              children: [
                const SizedBox(
                  height: 30,
                ),
                Text("count: ${model.counter}"),
                const SizedBox(
                  height: 30,
                ),
                if (child != null) child
              ],
            );
          },
        ));
      }
    }

     

    Widget에서 Consumer 를 이용해서 ExampleModel 을 받아올 수 있다. Consumer 의 builder 인자는 ChangeNotifier가 변경될 때마다 실행되는 화면을 말한다. 여기 세가지 변수가 있다.

     

    1. context는 build 함수에서 받아온 context와 동일하다

     

    2. model은 ChangeNotifier를 뜻한다. 내부 클래스가 변경된 값은 여기에서 구독할 수 있다

     

    3. child 값은 ChangeNotifier의 변경에 영향을 받지 않는다. Consumer 에서 child 를 선언할 수 있고 builder에서 Consumer의 child 인자 값을 전달 받는다. child를 활용해서 ChangeNotifier의 변경에 영향을 받을 부분과 받지 않는 부분을 나눠 위젯을 최적화 시킬 수 있다.

     

    context.read<>() 를 사용하면 값의 변화를 받지는 않고 읽기만 할 수 있다. 카운터 값을 증가시키는 곳에서 increaseCount() 함수를 호출하는데 여기서는 변화를 감지할 필요가 없으므로 context.read 로 ChangeNotifier 인스턴스만 가져와서 호출했다. 

     

     

    다음과 같은 화면을 띄울 수 있다. 클릭한 만큼 값이 자동으로 업데이트된다. 

     

    전체소스

     

     

    flutter changenotifier sample

    flutter changenotifier sample. GitHub Gist: instantly share code, notes, and snippets.

    gist.github.com

     

     

    참고자료

     

     

    Simple app state management

    A simple form of state management.

    docs.flutter.dev

     

    '개발' 카테고리의 다른 글

    socketio redis adapter  (0) 2023.01.06
    dart - mixin  (0) 2023.01.04
    typeorm - OneToOne, OneToMany, ManyToMany  (1) 2022.11.29
    typeorm - definition, entity  (0) 2022.11.29
    flutter - BlocWidget  (0) 2022.10.06

    댓글

Designed by Tistory.