[Flutter] 우당탕탕 개발 일지4 - 상태 관리

Leona·2023년 10월 5일
0
post-thumbnail

리액트로 상태 관리 하다가 여기서도 상태 관리하니 그렇게 어렵지 않았다.
상 태 조 아 상태 관리하세용

상태 관리 패턴과 라이브러리

상태 관리를 위한 다양한 패턴과 라이브러리가 있다. setState(), Provider, Bloc... 등등 있다.
맡은 프로젝트는 provider를 사용해서 상태 관리 중이었다. 웹 개발할 때 provider를 많이 썼으니 대충 개념은 알고 있었으나 ChangeNotifier는 뭔지, 상태 변경할 때마다 notifyListeners()를 호출해야 하고, provider를 생성하는 방법 차이 등 전부 생소했다.
프로젝트를 거의 마무리한 지금은 provider 플러그인을 어느정도 사용할 수 있게 되었다. 그래서 다시 한번 정리하는 겸 포스팅한다.
(머리로는 아는데 글로 풀어쓰기 어려워 gpt의 도움을 받았음)

Provider

플러터 공식 라이브러리. Inherited Widget 기반으로, 상위 위젯에서 하위 위젯으로 데이터 전달할 때 유용하다.

패키지

Provider(https://pub.dev/packages/provider)

사용법

  1. 설치
    명령어를 입력해서 설치하거나 pubspect.yaml dependencies에 추가한 후 명령어 입력
    flutter pub add provider
    or
    dependencies:
      provider: ^6.0.5
    flutter pub get
  2. Provider 생성
    루트 위젯 builder에서 ChangeNotifierProvider로 감싸 provider를 생성한다.
  • create 속성으로 생성하기
    SomeProvider에 접근할 때마다 새로운 인스턴스가 생성된다. 상태가 변경되지 않아야 하거나 상태 호출 할 때마다 초기화 해야 하는 경우 적용

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(
        ChangeNotifierProvider(
          create: (context) => SomeProvider(),
          child: MyApp(),
        ),
      );
    }
  • value 속성으로 생성하기
    단일 인스턴스 생성, 해당 Provider를 구독하고 있는 모든 Consumer가 공유한다. 변경될 상태를 공유해야 하는 경우 적용
    나의 경우 여러 화면에서 Provider 하나를 바라보아야 했기 때문에 value로 생성했다.

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(
        ChangeNotifierProvider(
          value: SomeProvider(),
          child: MyApp(),
        ),
      );
    }
  • dispose
    리소스를 해제하거나 메모리 누수를 방지하기 위한 메소드로, create는 자동으로 dispose를 호출하지만 value는 수동으로 호출해야 한다.

  1. 상태 클래스 생성
    ChangeNotifier를 확장해서 클래스를 생성한다.
    provider 패키지와 함께 상태 관리하기 편하고, 상태 변화를 알려야 하기 때문에 ChangeNotifier를 확장한다.
    notifyListeners() 메소드로 상태 변화를 알릴 수 있다.

    import 'package:flutter/material.dart';
    
    class SomeProvider extends ChangeNotifier {
      int _count = 0;
    
      int get count => _count;
    
      void increment() {
        _count++;
        notifyListeners();
      }
    }
  2. Provider 사용하기
    Consumer 위젯으로 자식 위젯을 감싸 provider를 구독하고 상태 변경을 감지하면 리렌더링한다.

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    class MyApp extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Provider Example'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'Counter:',
                  ),
                  Consumer<SomeProvider>(
                    builder: (context, counter, child) {
                      return Text(
                        '${counter.count}',
                        style: TextStyle(fontSize: 24),
                      );
                    },
                  ),
                  ElevatedButton(
                    onPressed: () {
                      Provider.of<SomeProvider>(context, listen: false).increment();
                    },
                    child: Text('Increment'),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }

Bloc(Business Logic Component)

써보진 않았지만 Bloc 패턴도 많이들 쓴다고 한다. 패키지로 비즈니스 로직 관리, 스트림으로 상태를 전달한다.


setState

stateful widget에서 간단하게 상태 변경할 때 썼다. 전역으로 관리하지 않아도 될 때 유용한 것 같다.


Redux

여기도 redux 패키지가 있다. 리액트 개발할 때 redux 이해하고 구성하느라 진이 빠진 기억이 있는데 스토어로 상태 관리한다고 하니 여기도 어려울 것 같다.

상태 관리 패턴은 프로젝트 규모나 성격에 따라 적용해야 하는데 아직도 제일 효율적이고 알맞는 것인지 모르겠다. 체감할 수 있는 성능 차이가 크지 않기 때문에 더 어려운듯 하다.

profile
레오나의 기묘한 개발 일지

0개의 댓글