Flutter Bloc 사용 후기

JhoonP·2022년 9월 25일
0
post-thumbnail

Flutter에서 상태관리를 할 수 있는 방법으로 크게 3가지를 알고 있다.

  1. GetX
  2. provider
  3. flutter_bloc

업무 초기 당시에는 Flutter를 빠르게 적용해야 했다.
따라서 context를 관리가 필요 없으면서 navigation, Widget building, state management 모두를 할 수 있는 GetX를 사용하였다.

하지만 context 관리가 필요 없다는 뜻은 결국 관리를 GetX에 전부 위임한다는 뜻이다.
만약 BuildContext 관련 큰 설계 변경이 생기고 이것이 GetX와 호환되지 않는다면?
GetX로 만들어진 기존 앱을 사용할 수 없게 될 수도 있다.

그리고 실제로 이미 GetX의 dialog와 관련하여 문제를 겪은 적이 있다

dialog 보다 상단에 있는 snackbar를 건드리지 않으면서 dialog만 직접 pop 해야하는 경우가 있었는데,
GetX의 dialog에서 context를 빼내는 방법을 찾지 못해 결국 기존 showDialog를 사용해야 했다.

따라서 새로운 프로젝트에서는 GetX를 사용하지 않고 flutter_bloc를 사용하기로 결정하였다.

flutter_bloc

BLoC(Business Logic Component) 디자인 패턴은 presentation 영역과 business logic 영역을 명확하게 분리하여 각 영역의 역할을 확실히하고 재사용과 테스트 코드 작성 또한 가능하게 해주는 패턴이다.

Flutter에서는 이러한 BloC 패턴을 쉽게 적용할 수 있도록 flutter_bloc 패키지를 제공하고 있다.


BLoC 아키텍처는 크게 3가지 영역으로 분리된다

  • presentation을 담당하는 UI
  • Business Logic을 담당하는 Cubit
  • 데이터 처리를 담당하는 Data

presentation 영역인 UI는 cubit의 state를 참조하여 Widget building을 수행한다.
UI에서 cubit의 함수를 호출하면 cubit에서는 여러 business logic을 수행하여 새로운 state를 생성한다.
그리고 다시 해당 state를 UI에 전달하면, UI는 새로운 state으로 빌드된다.

function call에 따라 상태를 변경하는 Cubit 이전에 event base인 Bloc라는 것이 있지만,
아직은 사용하고 있지 않으니 넘어간다.
Cubit vs. Bloc

State

state는 불변 객체를 사용하도록 권장하고 있다

따라서 state는 기존 instance에서 특정 property만 변경하는 것은 불가능하고,
state를 변경하려면 무조건 새로운 state를 생성해야만 한다.

이러한 특성이 기존 아키텍처 패턴들(MVC, MVP, MVVM 등)과의 차이점이라고 생각한다.
Flutter BLoC 에서는 state의 일부 property를 변경하기 위해서 무조건 새로운 state를 생성하여 방출해야 하고
이러한 과정은 UI 업데이트를 강제하여 state 변경이 UI에 적용되지 않는 불상사를 방지해준다.

state class를 정의하는데 flutter_bloc는 Equatable을 사용하도록 제안하고 있지만,
state를 변경하는데 자주 사용하게 되는 copyWith 함수까지는 기본 제공해주고 있지 않아,
개인적으로는 operator ==copyWith 코드를 자동생성 해주는 freezed package를 사용하고 있다.
혹시 freezed를 사용에 문제가 있는 경우를 알고 있는 분이 있다면 알려주시면 감사하겠습니다.

사용 후기

GetX의 위험성에서 벗어났다는 점, 불변객체인 state를 사용해 UI를 업데이트 함으로써
state management 지옥에서 어느정도 벗어날 수 있었다는 점은 좋았지만,

가끔 그닥 크지 않은 페이지에도 Cubit, state를 위한 boilerplate 코드를 따분하게 작성하거나
페이지 push 시 상위 페이지의 Cubit을 하위 페이지로 어떻게 넘길지도 고민하고(일단은 공식 문서 제안대로 사용하고 있지만 걸리는 부분이 있다...)
UI 외부영역에서 dialog, snackbar를 호출해야 하는 case에서는 GetX가 그리워 질 때가 있다...

특히 Flutter에서 공식으로 제공하고 있는 라우팅 패키지인 go_router를 사용하다가
navigator key를 제공해주지 않는 다는 것을 알게 되었을 때는 어떻게 해야하나 싶었다
(다행히도 그 고민을 하기 3일(!) 전에 해당 기능의 업데이트 Changelog를 보고 package upgrade를 수행해 무사히 구현할 수 있었다...)

GetX를 들어내는 길은 멀고도 험하다,,,

profile
배울게 끝이 없네 끝이 없어

0개의 댓글