ETC/Flutter

[flutter] GetX 상태관리에 대해 알아보자

dkswnkk 2021. 11. 9. 20:16

 

Flutter 에는 상태 관리를 도와주는 Provider, block, GetX 등 여러 가지가 도구가 있다. 그중에서 GetX에 대해서 알아보려고 한다.

 

상태 관리를 왜 해야 할까?

 

Simple app state management

A simple form of state management.

flutter.dev

위의 공식 문서를 살펴보면 알겠지만, flutter는 widget안에 widget으로 구성되고 그 widget은 또 widget으로 구성되는 이른바 트리구조로 구현되어있다.

트리구조 예시

만약 최하단 위젯에서 최상단 부모 위젯으로 data를 보내면 어떨까? 또는 다른 페이지의 위젯으로 data를 보내면 어떨까? 하나의 data를 사용하기 위해서 매번 여러 페이지에서 정보를 불러온다면 앱의 규모가 커질수록 코드가 복잡해지고 여간 쉬운 일이 아니다. 

그래서 우리는 상태 관리 도구들을 사용하여 코드의 로직을 분리시켜 예) UI, Network, DB 만 담당하는 클래스로 나눈다 사용할 수 있다.

 

 

 

GetX의 특징

  • context 없이 routing 이 관리된다(엄청 편하다). ex) Get.to(SomePage())
  • 일반적으로 dispose(처분) 관리를 해야 하나, getX를 사용하면 기본적으로 dispose가 수행된다. 
  • binding을 이용해 business logic과 view를 분리할 수 있다.
  • 사용법이 단순하다.
  • 꾸준한 업데이트 덕분에 패키지 관리가 잘 되고 있다.

 

우리는 흔히 business logic data를 Controller에 위치시키고, 화면 구성요소(view, widget)에서 이러한 데이터를 가져다가 쓴다. getX에서는 이러한 Controller를 GetxController라고 한다.

 

GetxController 특징

  • controller는 business logic이 위치한다.
  • view에서 이를 쉽게 가져다가 쓸 수 있다.
  • dispose를 따로 해주지 않아도 navigation stack에서 빠질 때 자동으로 dispose 된다.
  • oninit(): initState()
  • onReady(): widget이 스크린에 다 그려진 후 발생하는 이벤트 메서드
  • onClose(): dispose()

 

GetBuilder, GetX, Obx 

GetX에서는 GetxController에서 데이터를 가져와 가공하는 세 가지 방법이 있다.

1. GetBuilder

  • getcontroller와 상호작용할 widget
class Controller extends GetxController {
  int counter = 0;

  void increment() {
    counter++;
    update(); // -> 변화를 notifty 한다.
  }
}
GetBuilder<Controller>(
  init: Controller(), // => app의 어디서든 최초 1회만 호출 하면 된다.
  builder: (value) => Text(
    '${value.counter}',
  ),
),

GetBuilder<Controller>(
  builder: (value) => Text(
    '${value.counter}',
  ),
),
  • GetBuilder는 stateful widget을 대신할 수 있다.
  • unique id를 줘서 구분할 수 있다.
  • 빠르고, 메모리 비용이 저렴하지만 reactive 하지 않다.

 

2. getX

  • stream 방식이다. StreamBuilder와 비슷
  • RxInt, RxString 등으로 변수 사용.
  • 모든 class 객체도 사용 가능 myClass().obs 형태로 선언
    class Controller extends GetXController {
      var count = 0.obs;  // RxInt 타입
    
      void iuncrement() => counter.value++;
    }​
    GetX<Controller>(
      init: Controller(),
      builder: (val) => Text(
        '${val.counter.value}',
      ),
    ),​

 

3. Obx

  • 사용 문법이 가장 단순
  • GetX는 get.find를 통해 사용하던 instance를 찾을 수 있다. 같은 instance를 공유
class User {
  String? name;
  User({this.name});
}


class Controller extends GetxController{
  var user = user{name: "cat"}.obs;   // 사용자 정의 User 클래스
  
  void changeName() => user.value.name = "Garg";  // value로 접근
}

Obx(() => Text( //Obx로 감사쭈면 끝, user 변화 catch 및 적용
  '${controller.user.value.name}'
 ),
),
class PageOne extends StatelessWidget {

  Controller controller = Get.put(Controller());    // contriller binding 필요

}
class PageSeven extends StatelessWidget{
  Controller controller = Get.find(); // 다른 widget에서 controller에 그대로 access 가능
}

 

요약

  • GetBuilder: 가장 빠름, Stream 사용 안 함, State를 builder들 간에 공유함. Ram 절약
  • GetX: value가 실제로 바뀌었을 때만 reDraw 함, controller를 instance화 하지 않음
  • Obx: 문법 간단, 하나의 위젯에서 여러 개의 controller 사용 가능, binding 편함

 

 

참고

 

개소리-개발자의 목소리

Software, Programming, IT 기술에 대해 공부하는 채널 입니다. 최신 기술 동향 및 강의 영상이 upload 됩니다. 감사합니다.

www.youtube.com