728x90
반응형
Flutter에서 앱을 개발하다 보면, 가장 먼저 부딪히는 벽 중 하나가 상태 관리(State Management)다.
버튼을 누를 때 숫자가 바뀌고, 로그인하면 프로필 화면으로 이동하고, 장바구니에 담은 상품이 모든 화면에 반영되는…
이런 변화들을 어떻게 "잘" 처리할 수 있을까?
그 해답 중 하나가 바로 Provider.
🌱 Provider란?
Provider
는 Flutter에서 가장 많이 사용되는 상태 관리 도구 중 하나다.
Google에서도 공식적으로 추천하고 있으며, 아래의 기능을 중심으로 작동한다:
- 의존성 주입(Dependency Injection)
- 상태 변화 알림(Notification)
데이터를 전역에서 관리하고,
변경되었을 때 자동으로 필요한 위젯만 갱신되게 도와주는 친구.
🧠 Provider를 왜 써야 할까?
Flutter의 기본 StatefulWidget만으로도 상태를 관리할 수 있다.
하지만 아래와 같은 상황에서 한계가 드러난다:
- 여러 위젯이 같은 데이터를 사용하고 싶을 때
- 하위 위젯에서 상위 위젯의 상태를 바꾸고 싶을 때
- 앱 전체에 로그인 정보, 유저 상태 등을 공유해야 할 때
이런 문제를 해결하기 위해 우리는 상태를 "분리"하고 "관리"해야 한다.
Provider는 이 구조를 간단하게 만들어준다.
🔧 Provider 종류
종류 | 설명 |
---|---|
Provider<T> |
가장 기본적인 의존성 주입용 Provider |
ChangeNotifierProvider |
상태 변경이 일어나는 클래스를 주입 |
Consumer |
특정 위젯에서 Provider의 상태를 감시 |
Selector |
필요한 값만 감시하는 고급 방식 |
MultiProvider |
여러 Provider를 한 번에 선언할 때 |
ProxyProvider |
다른 Provider 값을 기반으로 생성 |
🧪 기본 예제: Counter 만들기
1. Model 생성
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 모든 리스너에게 변경 사항 알림
}
}
2. main.dart에 Provider 등록
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: const MyApp(),
),
);
}
3. 위젯에서 상태 사용하기
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = context.watch<Counter>();
return Scaffold(
appBar: AppBar(title: const Text("Provider Example")),
body: Center(
child: Text('Count: ${counter.count}'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<Counter>().increment(),
child: const Icon(Icons.add),
),
);
}
}
🎯 watch vs read vs Consumer 차이
사용법 | 기능 |
---|---|
context.watch<T>() |
상태가 바뀌면 전체 위젯을 다시 그림 |
context.read<T>() |
상태를 읽지만 위젯은 다시 그리지 않음 |
Consumer<T>() |
특정 위젯에서만 rebuild 함 (세밀한 제어) |
📦 MultiProvider 사용법
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
ChangeNotifierProvider(create: (_) => ThemeModel()),
],
child: MyApp(),
)
🧬 ProxyProvider 예제
class ApiService {
final String token;
ApiService(this.token);
}
class UserModel extends ChangeNotifier {
final ApiService apiService;
UserModel(this.apiService);
// ...
}
MultiProvider(
providers: [
Provider<String>.value(value: "access_token_123"),
ProxyProvider<String, ApiService>(
update: (context, token, _) => ApiService(token),
),
ChangeNotifierProxyProvider<ApiService, UserModel>(
create: (_) => UserModel(ApiService("")),
update: (_, apiService, __) => UserModel(apiService),
),
],
child: MyApp(),
);
🔍 Selector로 최적화하기
Selector<Counter, int>(
selector: (_, counter) => counter.count,
builder: (_, count, __) => Text('Count: $count'),
)
🌈 Provider를 쓸 때 좋은 구조
models
폴더에 상태 관리 클래스providers
폴더에 MultiProvider 설정screens
폴더에 위젯 정의
🧭 마무리하며
Provider는 단순한 카운터 앱부터 시작해,
복잡한 비즈니스 로직이 들어간 앱까지 확장 가능한 구조를 갖추게 해 준다.
처음엔 어렵고 생소하지만, 구조를 하나씩 뜯어보다 보면
“앱이 어떻게 살아 숨 쉬는지”를 이해하게 되는 멋진 순간이 온다.
Provider는 Flutter 앱에 "심장"과 같은 역할을 한다.
데이터가 뛰고, 화면이 반응하고, 사용자가 만족하는 앱.
그 중심엔, 지금 배운 이 구조가 있다.
✍️ 이 글은 터미널 밖으로 나온 개발자의 Flutter 여정입니다.
728x90
반응형
'Flutter' 카테고리의 다른 글
Flutter에서 HTTP로 서버 데이터 불러오기 — 작은 연결이 만들어내는 큰 변화 (0) | 2025.05.19 |
---|---|
Flutter 애니메이션 & 전환 효과 완전 정복 — 감성을 더한 부드러운 움직임 만들기 (0) | 2025.05.16 |
Flutter에서 화면 전환은 이렇게! – Navigator 완전 정복 🌈 (0) | 2025.05.15 |
Flutter ListView로 다이나믹 UI 만들기 — 반복되는 위젯을 더 똑똑하게 그리는 법 (0) | 2025.05.15 |
Flutter 입문 기록 — 감성과 기능의 균형 속으로 (0) | 2025.05.14 |