일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Swift
- @Model
- 1주차
- 프로그래머스
- xcode15
- watchapp
- tutorials
- 2023
- 3주차
- Flutter
- tutorial
- ios
- 개발자
- 콩세알프로젝트
- 회고
- test
- WWDC
- KoreaMango
- watchkit
- 2주차
- swiftUI
- 티스토리챌린지
- 대학생협
- Apple
- ActivityKit
- unittest
- RxSwift
- Unit
- SwiftData
- 오블완
- Today
- Total
KoreaMango 나무
Flutter State Management - 1. Provider, ChangeNotifier 에 대해 본문
오늘은 Flutter의 상태관리에 대해 알아보려 합니다.
Flutter에서 데이터 상태관리를 하기 위해서는 여러가지 방법이 있습니다.
Provider, GetX, Bloc, ... 등등..
하지만 Flutter를 입문자라면 아마도 Provider를 통해서 데이터 상태관리를 할 것 입니다.
Flutter 공식 문서에서도 Flutter에서 Provider를 사용하는 것은 이해하기 쉽고, 코드를 많이 사용하지 않는다고 말합니다.
저도 provider가 Flutter에 기본적으로 내장되어 있는 줄 알았는데, 상태관리를 하기 위해서는 package를 설치해야 하더라구요.
https://pub.dev/packages/provider
여기 페이지를 참고하여 자신의 프로젝트에 추가해주시면 됩니다!
Provider를 사용하기 위해선 3가지 개념을 필수로 알아야 하는데요.
1. ChangeNotifier
2. ChangeNotifierProvider
3. Consumer
가 있습니다.
ChangeNotifier는 Flutter에 포함되어 있는 클래스로 Listener에게 변경 알림을 제공합니다.
사용 방법은
class CartModel extends ChangeNotifier {
/// Internal, private state of the cart.
final List<Item> _items = [];
/// An unmodifiable view of the items in the cart.
UnmodifiableListView<Item> get items => UnmodifiableListView(_items);
/// The current total price of all items (assuming all items cost $42).
int get totalPrice => _items.length * 42;
/// Adds [item] to cart. This and [removeAll] are the only ways to modify the
/// cart from the outside.
void add(Item item) {
_items.add(item);
// This call tells the widgets that are listening to this model to rebuild.
notifyListeners();
}
/// Removes all items from the cart.
void removeAll() {
_items.clear();
// This call tells the widgets that are listening to this model to rebuild.
notifyListeners();
}
}
이렇게 Class에 ChangeNotifier를 상속해주면 됩니다.
그리고 이 클래스의 상태값을 변경 시켜줬을 때, 리스너에게 전달을 하기 위해서는 notifyListeners();를 실행해줘야 합니다.
ChangeNotifierProvider는 위젯인데, 하위 항목에 ChangeNotifier의 인스턴스를 제공합니다.
ChangeNotifierProvider는 provider 패키지에 존재하므로 provider를 설치해야줘야해요 :)
ChangeNotifierProvider는 불필요하게 상위 계층에 놓을 필요가 없어요.
여러 개의 ChangeNotifierProvider를 하위 항목들에게 전달하고 싶으면 MutilProvider를 사용하면 됩니다 :)
/// ChangeNotifierProvider Example
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CartModel(),
child: const MyApp(),
),
);
}
/// MultiProvider Example
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CartModel()),
Provider(create: (context) => SomeOtherClass()),
],
child: const MyApp(),
),
);
}
마지막으로 Consumer에 대해 설명드리자면,
상위에서 상태값을 갖고 있는 ChangeNotifier, 넘겨주는 ChangerNotifierProvider가 있으면, 상태를 사용하는 곳도 있어야겠죠.
그 상태를 사용하려고 받는 위젯을 Consumer 위젯이라고 합니다.
이 Consumer 또한 ChangerNotifierProvider와 똑같이, 굳이 상위에서 쓸 필요가 없습니다.
가장 좋은 예시는 딱 사용하는 부분만 Consumer로 덮어주는거죠.
// DON'T DO THIS
return Consumer<CartModel>(
builder: (context, cart, child) {
return HumongousWidget(
// ...
child: AnotherMonstrousWidget(
// ...
child: Text('Total price: ${cart.totalPrice}'),
),
);
},
);
// DO THIS
return HumongousWidget(
// ...
child: AnotherMonstrousWidget(
// ...
child: Consumer<CartModel>(
builder: (context, cart, child) {
return Text('Total price: ${cart.totalPrice}');
},
),
),
);
이렇게 말입니다.
추가적으로 Provider에 있는 함수를 가져오고 싶지만, 계속 Listen을 할 필요가 없으면, Listen을 끊어줄 수 있다고 하네요.
Provider.of<CartModel>(context, listen: false).removeAll();
리소스를 비교적 크게 먹는 Consumer라는 위젯을 사용하지 않고, 이렇게 사용해서 ChangerNotifier를 상속한 클래스에 접근한 다음,
메소드를 실행할 수 있습니다.
위의 예시는 CartModel에 있는 removeAll이라는 함수를 실행시키는 예시 입니다.
provider 패키지에서 context에 extension으로 Provider.of를 조금 더 축약시켜놓은
context.read 와 context.watch가 있으니 이것도 알아보시면 좋을 것 같네요 :)
출처: https://docs.flutter.dev/data-and-backend/state-mgmt/simple
Flutter 상태 관리의 가장 기본인 Provider에 대해 간단하게 알아봤는데요.
정말 쉽긴 한 것 같아요.
그런데 조금 더 체계적인 아키텍처에서 사용하기에는 ChangeNotifierProvider와 Consumer가 중구난방으로 쓰일까봐 걱정이 되긴 하네요.
다음에는 GetX와 Bloc에 대해서도 알아보면 좋을 것 같아요.
그리고 dart 코드 블럭을 못 찾고 있는데, 글 작성할 때 dart 코드블럭 사용하는 방법에 대해 아시는 분 계신가요?..
'Flutter' 카테고리의 다른 글
Flutter - 플러터의 메모리 관리 (1) | 2024.11.12 |
---|---|
Flutter - Class의 확장 방법 (2) | 2024.11.11 |
Flutter - secure_storage || KeyChain 사용법 (feat. Method Channel) (0) | 2024.11.10 |
Flutter - Build Context란? (1) | 2024.11.08 |