Provider
Provider (Flutter 상태 관리 라이브러리)
Provider란?
Provider는 Flutter에서 가장 널리 사용되는 상태 관리 라이브러리 중 하나로, Google에서 권장하는 도구입니다. 이 라이브러리는 Flutter 애플리케이션에서 **의존성 주입(Dependency Injection)**과 **상태 관리(State Management)**를 간단하고 효율적으로 처리할 수 있도록 설계되었습니다.
Provider가 필요한 이유
Flutter의 상태 관리를 위해 setState를 사용할 수 있으나, 다음과 같은 문제가 발생할 수 있습니다:
상태가 복잡해질수록 setState로 관리하기 어려워집니다.
위젯 트리가 깊어질수록 특정 상태를 다른 위젯에 전달하기 어려워집니다.
테스트가 복잡해집니다.
Provider 설치:
flutter pub add providerpubspec.yaml에 다음 의존성을 추가합니다:
dependencies:
provider: ^6.1.5의존성을 가져옵니다:
flutter pub getProvider는 이러한 문제를 해결하며 다음과 같은 이점을 제공합니다:
상태 공유: 여러 위젯 간 상태를 손쉽게 공유할 수 있습니다.
효율적인 빌드: 변경된 부분만 다시 렌더링하여 성능을 최적화합니다.
코드 구조화: 상태와 UI를 명확히 분리하여 유지보수가 용이합니다.
Provider의 주요 개념
ChangeNotifier
ChangeNotifier는 Flutter에서 상태 변화를 알리는 간단한 클래스입니다.
상태가 변경되면 **구독자(위젯)**에게 알립니다.
import 'package:flutter/material.dart';
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 상태 변경 알림
}
}ChangeNotifierProvider
ChangeNotifierProvider는 ChangeNotifier를 위젯 트리에 제공하는 역할을 합니다.
이를 통해 위젯에서 상태를 구독할 수 있습니다.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(), // 상태 객체 생성
child: MyApp(),
),
);
}Consumer
Consumer는 ChangeNotifier의 상태를 구독하며, 상태가 변경될 경우 UI를 다시 렌더링합니다.
필요한 부분에서만 상태를 구독할 수 있어 효율적입니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Provider Example')),
body: Center(
child: Consumer<Counter>(
builder: (context, counter, child) {
return Text('Count: ${counter.count}');
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context, listen: false).increment();
},
child: Icon(Icons.add),
),
),
);
}
}Provider.of
Provider.of를 사용하여 상태에 접근할 수 있습니다.listen 속성을 통해 상태 변경을 구독할지 여부를 설정할 수 있습니다.
final counter = Provider.of<Counter>(context, listen: false);
counter.increment();MultiProvider
MultiProvider를 사용하면 여러 상태를 한 번에 제공할 수 있습니다.
대규모 애플리케이션에서 매우 유용합니다.
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Counter()),
ChangeNotifierProvider(create: (context) => AnotherState()),
],
child: MyApp(),
),
);
}Provider의 전체 흐름
모델 생성:
ChangeNotifier를 상속하여 상태 관리 모델을 생성합니다.
Provider 설정:
ChangeNotifierProvider또는MultiProvider를 사용해 상태를 위젯 트리에 제공합니다.
상태 접근:
Provider.of또는Consumer를 사용해 상태를 구독하고 UI를 업데이트합니다.
Provider의 장점
간단한 API:
- Flutter 초보자도 쉽게 사용할 수 있습니다.
효율성:
- 필요한 위젯만 다시 렌더링하여 성능을 최적화합니다.
유연성:
- 다양한 구조와 조합이 가능합니다.
구글 권장:
- Google에서 공식적으로 추천하는 패턴으로 안정성과 신뢰성을 제공합니다.
Provider의 단점
의존성 증가:
- 라이브러리에 의존하므로 학습이 필요합니다.
코드 중복 가능성:
- 상태가 많아질수록 코드가 중복될 가능성이 있습니다.
Provider의 심화 기능
Selector
상태의 특정 부분만 구독하여 불필요한 리렌더링을 방지합니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Selector Example')),
body: Selector<Counter, int>(
selector: (context, counter) => counter.count,
builder: (context, count, child) {
return Text('Count: $count');
},
),
),
);
}
}FutureProvider
비동기 작업의 결과를 상태로 관리합니다.
final futureProvider = FutureProvider<int>((context) async {
return await fetchData();
});
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final data = Provider.of<int>(context);
return Text('Data: $data');
}
}StreamProvider
스트림 데이터를 상태로 관리합니다.
final streamProvider = StreamProvider<int>((context) {
return Stream.periodic(Duration(seconds: 1), (count) => count);
});