본문 바로가기
flutter

플러터 - Bloc Cubit

by 들풀민들레 2023. 3. 13.

 

본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

큐빗이란?


bloc 패키지를 이용할 때 Bloc를 상속받은 클래스를 작성하고 이 클래스에 이벤트를 주입해 등록된 이벤트로 업무 로직을 실행합니다. 그런데 Bloc 클래스 대신 큐빗cubit 클래스를 이용할 수도 있습니다. Bloc와 큐빗 클래스는 역할은 같지만 동작 방식에 차이가 있습니다. Bloc 클래스는 이벤트 주도 방식이며 이미 살펴본 것처럼 이벤트를 먼저 정의하고 이 이벤트를 Bloc 클래스에 등록하여 위젯에서 Bloc 클래스에 이벤트가 발생할 때 등록된 내용을 실행하는 방식입니다.

 

그런데 큐빗은 함수 직접 호출 방식입니다. 큐빗의 구조는 Bloc의 구조와 거의 비슷합니다. 단지 UI에서 큐빗을 이용할 때 이벤트를 주입하는 것이 아니라 함수를 호출하여 함수에 정의된 로직을 실행하고 상태 데이터를 유지하는 방법입니다.
오른쪽 그림은 큐빗의 흐름을 나타냅니다. 큐빗의 함수가 호출되면 업무 로직이 실행되고 상태를 내보냅니다. 그러면 내부적으로 onChange() 함수가 자동으로 호출되어 상탯값 변경 정보를 전달해 줍니다.

 

큐빗 작성하기
큐빗은 Cubit 클래스를 상속받아 작성합니다. Cubit<int>처럼 제네릭으로 Cubit 클래스에서 내보내는 상태의 타입을 지정합니다. 그리고 상위 클래스의 생성자를 호출하면서 매개변수로 상태의 초깃값을 지정합니다. 다음 코드에서 CounterCubit은 int 타입의 상태를 내보내는 Cubit 클래스이며 초깃값을 0입니다.

class CounterCubit extends Cubit<int> {
    CounterCubit() : super(0);
    void increment() => emit(state + 1);
    void decrement() => emit(state - 1);
    @override
    void onChange(Change<int> change) {
        super.onChange(change);
        print('${change.toString()}');
    }
}

이렇게 선언한 Cubit 클래스를 위젯에서 이용할 때 Bloc처럼 이벤트를 주입하지는 않습니다. 그러므로 큐빗을 이용한다면 열거형 상수나 클래스로 이벤트를 선언할 필요가 없습니다. 또한 onEvent() 함수도 제공하지 않으며 on()으로 이벤트 핸들러를 등록할 필요도 없습니다.
단지 큐빗을 이용하는 곳에서 호출할 함수를 Cubit 클래스에 선언하면 됩니다. 이 예에서는 increment(), decrement() 함수이며 위젯에서는 이 함수를 직접 호출합니다. 큐빗의 함수에서는 적절한 업무 로직을 실행하고 결과 데이터를 emit() 함수로 내보내면 이 데이터를 하위 위젯이 이용합니다.
큐빗에는 개발자 함수 외에도 onChange() 함수를 재정의할 수 있습니다. 이 함수는 어디선가 emit() 함수로 상태를 내보내면 자동으로 호출됩니다. onChange() 함수의 매개변수인 Change 객체를 이용해 이전 상탯값과 변경된 상탯값을 정보로 얻을 수 있습니다. 앞의 코드처럼 실행하여 어디선가 increment() 함수를 호출하면 onChange()의 print() 함수가 다음처럼 출력합니다.

큐빗 이용하기
큐빗을 이용하는 위젯 쪽 코드는 Bloc와 차이가 없습니다. 위젯에서 큐빗을 이용하려면 BlocProvider로 큐빗 객체를 등록합니다.

BlocProvider(
    create: (_) => CounterCubit(),
    child: MyWidget(),
)

이처럼 BlocProvider로 등록한 큐빗 객체를 하위 위젯에서 얻을 때는 BlocProvider.of()를 이용하거나 BlocBuilder를 이용해도 됩니다. 즉, Bloc 이용과 차이가 없습니다. 단지 Bloc를 이용할 때는 add() 함수로 이벤트를 주입했지만, 큐빗은 큐빗에 선언된 함수를 바로 호출합니다.

class MyWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        var cubit = BlocProvider.of<CounterCubit>(context);
        return BlocBuilder<CounterCubit, int>(
            builder: (context, count) {
                return Row(
                    children: <Widget>[
                        Text('Cubit : $count',),
                        ElevatedButton(
                            child: Text('increment'),
                            onPressed: () {
                            	cubit.increment();
                        	},
                        ),
                        ElevatedButton(
                            child: Text('decrement'),
                            onPressed: () {
                            	cubit.decrement();
                            },
                        )
                    ],
                );
            },
        );
    }
}

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

 

'flutter' 카테고리의 다른 글

플러터 - BasicMessageChannel  (0) 2023.03.13
플러터 - GetX로 상태 관리하기  (0) 2023.03.13
플러터 - Provider  (0) 2023.03.13
플러터 - InheritedWidget  (0) 2023.03.13
플러터 - Isolate  (0) 2023.03.13