개발을 시작하는 이야기

Flutter의 상태관리 01 본문

개발 이야기/Flutter

Flutter의 상태관리 01

Teiresias 2024. 6. 15. 20:55

Flutter에서는 상태관리를 위해 GetX, BLoC, Provider, Riverpod 같은 상태관리 패키지들이 있다. 상태관리라는 단어가 처음에는 어색했는데, 결국 사용자가 앱을 사용하며 변경되는 데이터를 관리하는, ViewModel과 같은 역할을 하는 것이다. 사용자의 로그인 상태, 화면에 표시될 데이터, 선택한 항목 들을 관리하게 되는데, 이를 효율적으로 수행하지 않으면 상태 반영이 재대로 이뤄지지 않거나, 코드가 복잡해지고 유지보수가 어려워지는 문제가 발생할 수 있다.

 

Flutter에서는 변경된 상태를 UI에 반영하기 위해서는 위젯을 다시 빌드해야 한다. createState()로 위젯 트리를 호출하고 상태를 별도의 State에 저장을 한다. 상태를 변경하기 위해서는 initState() 혹은 setState()를 호출해 수정된 상태로 UI를 다시 그려줄 수 있다. 하지만 setState() 만으로 상태관리를 하기엔 몇가지 문제가 있다. 기본적으로 위젯은 트리 구조로 위젯의 상태를 변경하면 그 위젯과 하위 위젯 전부 build()가 호출되어 UI가 렌더링이 되기 때문에 성능이 저하되거나 원하지 않는 동작이 발생할수 있다.

 

Flutter 공식문서의 설명을 보면 다음과 같은 경우를 예로 들고 있다. MyCatalog의 MyListItem의 각 위젯을 터치해 장바구니에 담고, MyCart에서 담은 목록을 확인하는 앱이라고 하면, 장바구니 상태를 업데이트해서 UI를 바꾸면 위젯을  다시 빌드하게 되는데, 트리 구조로 인해 이 상태는 바뀌는 위젯 또는 위젯의 상위에 있어야 한다. 그래서, Cart의 상태를 MyApp에서 관리하게 되면, MyApp에서 setState()를 호출하게 되면 Cart를 사용하지 않는 MyAppBar또한 불필요하게 렌더링 되게 된다.

 

그리고 위젯의 상태를 다른 위젯에서 사용하는 경우, 위젯의 생성자로 상태를 넘겨야 하는데 위젯트리가 복잡해지고 싶어지면 데이터를 사용하지 않는 위젯도 거쳐야 하는 문제가 발생한다.A위젯에서 생성된 Data를 C위젯에서 사용하기 위해서 B위젯을 거쳐서 사용하게 되면 B위젯은 Data를 사용하지 않지만 C에서 사용하기 위해 상태를 전달했다. 다음과 같이 상태를 전달해서 필요한 위젯에서 사용하는 방법이 아니라, 모든 위젯이 데이터를 공유하는 InheritedWidget을 사용하거나 별도의 상태관리 라이브러리를 사용하는 방법이 있다. GetX, BLoC, Provider, Riverpod등이 있다.

class AWidget extends StatelessWidget {
  final String data = 'string';
  const A();

  @override
  Widget build(BuildContext context) {
    return Container(
      child: BWidget(data),
    );
  }
}

class BWidget extends StatelessWidget {
  final String data;
  const BWidget(this.data);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: CWidget(data),
    );
  }
}

class CWidget extends StatelessWidget {
  final String data;
  const CWidget(this.data);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(data),
    );
  }
}
  GetX BLoC Provider Riverpod
장점 - 러닝커브가 낮고 생산성이 높아 인기가 많은편

- 상태관리 외에도 Navigation, HTTP, Dialog등 다양한 기능을 제공한다.

- BuildContext, StatefulWidget을 쓸 필요가 없다.
- 비지니스 로직에서 UI를 분리하기 쉽다. (.dart 파일을 분명하게 분리 가능)

- Stream을 이용해야 한다면 강력한 라이브러리다 (ex 체팅)

- UI에서 발생하는 이벤트를 감지한다.
- Flutter 공식문서에서도 사용하는 라이브러리

- BuildContext를 활용하며 Flutter 자체를 최대한 활용하는 형식
- Provider의 단점을 보완해서 나온 라이브러리다.

- Flutter에 의존하지 않고 Dart만으로도 사용이 가능하다.

- 컴파일타임 동안 안전하다
단점 - Flutter의 중요 객체나 라이프 사이클을 사용하지 않기 때문에 기본을 배우기엔 좋지 않다. - Stream을 이용하기 때문에 러닝커브가 높은편이다. - Provider를 개선해 Riverpod을 출시했기 때문에 deprecated될 가능성이 있다.   

 

이중에 내가 알아갈것은 Provider 그리고 Riverpod이다.

'개발 이야기 > Flutter' 카테고리의 다른 글

Flutter의 Hooks 사용하기 01  (0) 2024.06.17
Flutter의 상태관리 02  (0) 2024.06.16
객체지향 프로그래밍 정리  (1) 2024.06.14
Android Google Cloud용 SHA-1 생성  (0) 2024.06.05
BuildContext  (0) 2024.01.14