[Flutter] 상태 관리

saewoohan·2023년 8월 10일
0

Flutter

목록 보기
5/12
post-thumbnail

1. 상태 관리

  • 상태 관리란 앱이 사용자와 상호작용 하면서 변경되는 데이터를 관리 하는 것이다. 즉, 앱의 데이터를 효율적으로 관리하고 UI와 데이터 사이의 상호작용을 관리하기에 중요하다.
  • 특히 flutter는 선언형 UI이며, 각각의 상태를 포함하고 있는 widget tree로 구성되고 있기에 상태 관리가 중요해진다. 단일 위젯에서만 해당 상태를 사용한다면 문제 되지 않지만, 여러 위젯 특히 depth차이가 많이 나는 곳에서 서로 연관성이 있다면 더욱 중요해진다.
  • Flutter에서는 여러 가지 상태 관리 방법이 존재하며, 각 방법은 앱의 크기와 복잡성에 따라 선택할 수 있다.

1) setState()

  • 가장 기본적이고 간단한 상태 관리 방법으로, Stateful 위젯 내부에서 사용된다.
  • setState()를 호출하여 상태를 업데이트하면 해당 위젯의 build() 함수가 호출되어 UI가 업데이트 된다. 하지만 큰 규모의 앱에서는 관리하기 어렵고 성능 이슈가 발생할 수 있습니다.
class CounterWidget extends StatefulWidget {
  @override
  _CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text('Counter: $_counter'),
        ElevatedButton(
          onPressed: _incrementCounter,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

2) Provider

  • Provider는 의존성 주입을 사용하여 상태 관리를 하는 라이브러리이다. 앱 전역의 상태를 관리하거나 특정 위젯 트리의 일부 상태를 관리하는 데 사용됩니다. ChangeNotifier나 StreamProvider와 같은 클래스를 사용하여 상태를 제공하고 감지할 수 있다.
  • flutter 공식적으로 지원하는 방식이며, 난이도가 높지 않다.
class CounterProvider with ChangeNotifier {
  int _counter = 0;

  int get counter => _counter;

  void increment() {
    _counter++;
    notifyListeners(); // 상태 변경을 알림
  }
}

class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterProvider = Provider.of<CounterProvider>(context);

    return Column(
      children: <Widget>[
        Text('Counter: ${counterProvider.counter}'),
        ElevatedButton(
          onPressed: counterProvider.increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

3) Bloc

  • Bloc 패턴은 비즈니스 로직을 컴포넌트화하여 상태 관리를 하는 방법이다.
  • 채팅처럼 String이 수시로 오고가는 Stream에 사용하기에 적합하다고 한다.
class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0);

  void increment() => emit(state + 1);
}

class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterCubit = context.read<CounterCubit>();

    return Column(
      children: <Widget>[
        BlocBuilder<CounterCubit, int>(
          builder: (context, state) {
            return Text('Counter: $state');
          },
        ),
        ElevatedButton(
          onPressed: counterCubit.increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

4) GetX

  • GetX는 상태 관리 및 라우팅을 함께 제공하는 라이브러리로, 간단한 문법과 빠른 성능을 특징으로 한다. 주로 작은 규모의 앱에서 사용되며, 컨트롤러를 이용해 상태를 관리하고 업데이트한다.
  • flutter 자체의 문법과 다른 부분이 많기에 flutter가 아닌 새로운 getX라는 분야를 공부한다는 평이 자자하다.
class CounterController extends GetxController {
  var counter = 0.obs;

  void increment() {
    counter++;
  }
}

class CounterWidget extends StatelessWidget {
  final CounterController counterController = Get.put(CounterController());

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Obx(() => Text('Counter: ${counterController.counter.value}')),
        ElevatedButton(
          onPressed: counterController.increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

5) Riverpod

  • Provider 패키지의 개선된 버전이다. 사실 Flutter에서 공식적으로 Provider를 지지했기에 Riverpod도 마찬가지로 구글이 인정(?)한 패키지라고 할 수 있다.
  • Provider를 만든 사람이 개선해서 만든 버전이 Riverpod이기에 실제 프로덕팅에는 Riverpod을 놔두고 Provider를 사용할 메리트가 없다고 생각한다.
  • 또한, 현재 Riverpod을 사용하여 프로젝트를 진행 중이기에 추가적으로 Riverpod에 대해서 포스팅 하려고 한다.

0개의 댓글