
안녕하세요, 성조입니다.
오늘은 플러터의 상태관리 개념 중 하나인 Provider에 대해 간략히 정리하는 포스트를 작성해 봤습니다.
Provider란?
Provider는 Flutter의 내장 기능인 InheritedWidget을 기반으로 만들어진 상태 관리 패키지이다.
데이터(상태)를 위젯 트리(Widget Tree)의 상단에 올려두고 데이터가 필요한 하위 위젝들이 어디서든 쉽게 접근하고 사용할 수 있도록 도와주는 역할을 한다.
구글 측에서는 단순한 상태 관리를 진행할 때는 Provider 상태 관리를 권장하고 있다고 나온다.
다만, 실제 플러터 개발자들과 이야기를 나눠볼 때면 다른 상태 관리들을 선호하는 경우도 많고, 도메인에 맞게 다른 패키지들과 조합하여 버전에 맞게 사용하는 경우가 많이 있어서 그것들을 모두 고려하면 권장이나 기본기 작업에 좋은 것이지 그 외에 효율이 나온다고 정의하기 어렵다.

[공식 문서 링크]
https://docs.flutter.dev/data-and-backend/state-mgmt/simple
Simple app state management
A simple form of state management.
docs.flutter.dev
어떤 경우에 사용되는가?
1) Prop Drilling 방지 -> 부모 위젯에서 매우 먼 자식 위젯으로 데이터를 전달하기 위해 불필요한 생성자들을 통해 전달 전달해 주는 게 아닌 바로 전달할 수 있도록 기능한다.
2) 관심사 분리 -> UI를 그리는 코드와 비즈니스 로직(데이터 처리) 코드를 완전히 분리할 수 있어 코드의 가독성과 유지보수성이 크게 향상된다. 다만, AI주도 개발을 진행하는 요즘 같은 시대는 AI가 자기 멋대로 한 코드에 모두 때려 놓으니 스킬(skill) 같은 폴더 셋을 만들어서 구분 짓는 것이 아니라면, 상시적으로 리팩터링 하거나 문법을 미리인지하여 작업들을 사전에 작업들을 진행할 수 있도록 개선 반영들을 미리 구상해 놓는 것이 좋다.
3) 랜더링 효율화 -> 원하는 위젯만 선택적으로 다시 Rebuild 할 수 있는 장점이 있지만, 다른 상태관리 코드들도 해당 방식을 못하는 것이 아니기 때문에 올바른 값들의 반영들을 모두 고려하는 것이 좋다.
Provider 상태 관리 3가지
1) ChangeNotifier (상태 보관 & 알림)
역할 : 실제 데이터(상태)를 저장하고 관리하는 클래스로, Flutter에서 제공하는 기본 클래스이다.
활용 방법: 데이터가 변경되었을 때 notifyListeners() 메서드를 호출하면, 이 데이터를 바라보고 있는 위젯들에게 "데이터가 바뀌었으니 화면을 다시 그려줘"라고 신호를 보내는 용도로 사용된다.
2) ChangeNotifierProvider (상태 제공자)
역할: ChangeNotifier를 위젯 트리에 등록하여 하위 위젯들이 이 데이터에 접근할 수 있게 해주는 위젯이다.
활용 방법: 앱의 최상단(또는 데이터가 필요한 공통 부모 위젯의 경우)을 이것으로 감싸줘서 상태 데이터를 제어하는 데 사용된다.
3) Consumer & Context (상태 구독자)
역할: 제공된 데이터(상태)를 가져와서 화면에 보여주거나 데이터를 수정하는 위젯이다.
활용 방법: Consumer<T> 위젯을 사용하거나, context.watch<T>(), context.read<T>() 등의 확장 메서드를 사용하여 데이터에 접근하여 사용한다.
Provider 사용 예시
1. 패키지 설치
dependencies:
flutter:
sdk: flutter
provider: # 최신 버전 또는 본인의 프로젝트에 맞는 패키지 버전을 반영
2.ChangeNotifer를 활용한 상태 클래스 생성
import 'package:flutter/material.dart';
class CounterProvider with ChangeNotifier {
int _count = 0; // 프라이빗 변수로 상태 보호
int get count => _count; // 외부에서 값을 읽기 위한 getter
void increment() {
_count++;
notifyListeners(); // 값이 변경되었음을 알림 (UI 업데이트 트리거)
}
}
상태를 관리할 클래스를 생성하고 ChangeNotifier를 mixin(or 상속) 한다
3. ChangeNotifierProvider를 활용 및 적용
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
// MultiProvider를 사용하면 여러 개의 Provider를 한 번에 등록할 수 있습니다.
ChangeNotifierProvider(
create: (context) => CounterProvider(),
child: const MyApp(),
),
);
}
데이터를 사용할 위젯들의 공통 부모들을 ChangeNotifierProvider로 감싸준다.
보통 main() 쪽에서 생성 및 초기화를 많이 하다 보니 MaterialApp이 최상위로 올라가는 형식이다
4. watch, read를 활용하여 UI에서 데이터 상태 관리 및 사용
class CounterScreen extends StatelessWidget {
const CounterScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// context.watch: 데이터가 변경될 때마다 화면을 다시 그림
final counter = context.watch<CounterProvider>();
return Scaffold(
appBar: AppBar(title: const Text('Provider 예제')),
body: Center(
child: Text(
'현재 카운트: ${counter.count}',
style: const TextStyle(fontSize: 30),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// context.read: 데이터 변경 함수만 호출할 때 사용 (화면 리빌드 X)
context.read<CounterProvider>().increment();
},
child: const Icon(Icons.add),
),
);
}
}
하위 위젯에서 Provider의 데이터를 읽고 값이 변영될 때 맞춰서 변경한다.
상태 관리 사용 팁
1) context.watch<T>() or Consumer<T>
1-1) 언제 사용하는가? -> 화면에 상태 값을 보여주어 상태가 변할 때 화면도 같이 업데이트(rebuild) 되도록 구성할 때
1-2) 주의할 사항은? -> 이벤트 콜백 안에서는 사용할 수 없다. (onPressed, onTap 내부 등)
2) context.read<T>()
2-1) 언제 사용하는가? -> 버튼 클릭 등 이벤트를 발생시켜 상태를 변경하는 메서드를 호출할 때 사용한다. 단순히 값을 한 번만 읽고 더 이상 구독하지 않을 때를 말함.
2-2) 주의할 사항은? -> build 메서드 내에서 변수에 할당하여 UI를 그릴 때 사용하면, 데이터가 바뀌어도 화면 업데이트가 되지 않는 문제가 존재한다.
- 참조링크 -
(패키지 링크)
https://pub.dev/packages/provider
provider | Flutter package
A wrapper around InheritedWidget to make them easier to use and more reusable.
pub.dev
감사합니다.
다음 포스팅에서 뵙겠습니다.
'Flutter' 카테고리의 다른 글
| [Flutter] Unit Test(단위 테스트) 이해하기 (0) | 2026.03.16 |
|---|---|
| [Flutter] Color Class 가벼운 사용법 정리 (1) | 2026.03.13 |
| [Flutter] ListView 기초 정리 (0) | 2026.01.03 |
| [Flutter] Flutter Padding class 이해하기 (0) | 2026.01.02 |
| [Flutter] SingleChildScrollView 정리하기 (0) | 2026.01.01 |