Flutter for Beginners
Flutter의 상태 관리 기본 개념 (setState vs. Provider)
Andrew's Akashic Records
2025. 3. 14. 23:17
728x90
Flutter의 상태 관리 기본 개념 (setState vs. Provider)
Flutter에서 UI는 **상태(State)**에 따라 변경됩니다. 상태 관리(State Management)는 어떻게 데이터를 관리하고 UI에 반영할지를 결정하는 중요한 개념입니다.
1. 상태(State)란?
상태(State)란 UI가 변경될 때 필요한 데이터를 의미합니다.
예를 들어, 버튼 클릭 시 카운터가 증가하는 앱을 만든다면, 카운터 값(int counter)이 상태가 됩니다.
- StatelessWidget → 변하지 않는(정적인) UI
- StatefulWidget → 사용자 입력이나 이벤트에 따라 변경되는 UI
2. setState() (기본적인 상태 관리 방법)
setState()는 StatefulWidget 내에서 간단한 상태 관리를 할 때 사용됩니다.
예제: 버튼 클릭 시 카운터 증가 (setState 사용)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: CounterScreen(),
);
}
}
class CounterScreen extends StatefulWidget {
const CounterScreen({super.key});
@override
_CounterScreenState createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
int _counter = 0; // 상태 변수
void _incrementCounter() {
setState(() {
_counter++; // 상태 변경
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("setState 상태 관리")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("버튼을 누른 횟수:", style: TextStyle(fontSize: 18)),
Text(
"$_counter",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
child: Icon(Icons.add),
),
);
}
}
2.1. setState() 작동 방식
- _counter 변수를 setState() 내부에서 변경
- setState()가 호출되면 해당 위젯이 다시 빌드됨
- 새로운 _counter 값이 화면에 반영됨
- 간단한 상태 변경 시 사용 가능
- 상태가 여러 화면에서 공유될 경우 비효율적 (다른 위젯에서 값을 변경하기 어려움)
3. Provider (Flutter 공식 추천 상태 관리 방법)
Flutter 공식 문서에서는 규모가 큰 앱에서는 setState()보다 Provider를 사용할 것을 권장합니다.
Provider란?
- 전역적으로 상태를 관리하는 방법
- 여러 위젯에서 공통 상태를 쉽게 공유할 수 있음
- ChangeNotifier를 활용하여 상태 변경 감지
4. Provider 설치 및 설정
1단계: pubspec.yaml 파일 수정
dependencies:
flutter:
sdk: flutter
provider: ^6.0.5
터미널에서 패키지 설치
flutter pub get
5. Provider 사용 예제: 카운터 증가 앱
setState() 없이 Provider를 이용하여 상태를 관리해보겠습니다.
1단계: 상태 클래스 생성 (CounterProvider.dart)
import 'package:flutter/material.dart';
class CounterProvider with ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners(); // UI 업데이트
}
}
- ChangeNotifier를 상속받아 상태 변경 시 notifyListeners() 호출 → UI 자동 업데이트
2단계: main.dart에서 Provider 설정
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'CounterProvider.dart'; // 상태 클래스 import
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CounterProvider()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterScreen(),
);
}
}
- MultiProvider로 CounterProvider를 감싸서 전역적으로 상태를 공유할 수 있도록 설정
3단계: UI에서 Provider 데이터 가져오기
class CounterScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterProvider = Provider.of<CounterProvider>(context);
return Scaffold(
appBar: AppBar(title: Text("Provider 예제")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("버튼을 누른 횟수:", style: TextStyle(fontSize: 18)),
Text(
"${counterProvider.counter}",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: counterProvider.increment, // Provider 상태 변경
child: Icon(Icons.add),
),
);
}
}
- Provider.of<CounterProvider>(context)를 사용하여 counter 값과 increment() 메서드를 UI에서 직접 사용
6. setState() vs. Provider 비교
비교 항목 | setState() | Provider |
사용 범위 | 단일 위젯 내부에서만 사용 가능 | 여러 위젯에서 공통 상태 공유 가능 |
코드 유지보수 | 상태가 많아지면 복잡해짐 | 상태와 UI를 분리하여 유지보수 용이 |
UI 업데이트 방식 | setState() 호출 시 해당 위젯만 다시 빌드 | notifyListeners() 호출 시 관련 UI 자동 업데이트 |
성능 최적화 | 전체 위젯을 다시 빌드 | 필요한 위젯만 업데이트 |
추천 사용 사례 | 작은 규모의 앱 | 중~대형 앱 (전역 상태 관리 필요) |
상황 | 추천 방법 |
버튼 클릭 시 UI 변경 (단순 상태 변화) | setState() |
한 화면 내에서만 상태 유지 | setState() |
여러 화면에서 상태를 공유 | Provider |
데이터를 글로벌하게 관리 (예: 로그인 정보, 설정값) | Provider |
요약
setState()
- StatefulWidget에서 상태를 변경할 때 사용
- 간단한 UI 변경에 적합
- 여러 화면에서 상태를 공유하기 어려움
Provider
- Flutter 공식 추천 상태 관리 방법
- 여러 화면에서 상태를 쉽게 공유 가능
- 성능 최적화가 가능하며 유지보수 용이
728x90