Flutter 학습: 상태 관리
Flutter 애플리케이션을 개발할 때 중요한 부분 중 하나는 상태 관리입니다. 상태 관리를 통해 애플리케이션의 UI와 데이터 간의 일관성을 유지할 수 있습니다. 이번 글에서는 Flutter의 상태 관리 개념, 간단한 상태 관리 방법, 그리고 복잡한 상태 관리 방법에 대해 알아보겠습니다.
1. 상태 관리 개념: State 클래스, setState 메서드
State 클래스와 StatefulWidget: Flutter에서 상태가 변할 수 있는 위젯은 StatefulWidget을 사용하여 정의합니다. StatefulWidget은 상태를 저장하고 변경할 수 있는 State 객체를 가지고 있습니다.
State 클래스: State 클래스는 StatefulWidget의 상태를 관리합니다. 상태가 변경되면 UI를 다시 빌드하여 상태 변경을 반영합니다.
setState 메서드: setState 메서드는 상태를 변경하고, 변경된 상태를 반영하기 위해 UI를 다시 빌드하는 역할을 합니다.
예제:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterWidget(),
);
}
}
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('State Management Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
위의 예제에서 _CounterWidgetState 클래스는 _counter 상태를 관리하고, setState 메서드를 사용하여 상태를 업데이트합니다.
2. 간단한 상태 관리: Provider 패턴, ChangeNotifier
Provider 패턴: Provider 패턴은 간단하면서도 강력한 상태 관리 방법입니다. provider 패키지를 사용하여 쉽게 상태를 관리할 수 있습니다.
ChangeNotifier: ChangeNotifier는 변경 가능한 상태를 관리하는 클래스입니다. 상태가 변경될 때 리스너에게 알릴 수 있습니다.
예제:
1. pubspec.yaml에 provider 추가
dependencies:
flutter:
sdk: flutter
provider: ^6.0.0
2. ChangeNotifier 클래스 정의
class Counter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
3. Provider를 사용하여 상태 관리
import 'package:provider/provider.dart';
import 'counter.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterWidget(),
);
}
}
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Provider Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
),
Consumer<Counter>(
builder: (context, counter, child) {
return Text(
'${counter.count}',
style: Theme.of(context).textTheme.headline4,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<Counter>().increment(),
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
위의 예제에서 Counter 클래스는 ChangeNotifier를 상속받아 상태를 관리합니다. ChangeNotifierProvider를 사용하여 Counter 객체를 제공하고, Consumer를 사용하여 상태 변경을 감지합니다.
3. 복잡한 상태 관리: BLoC 패턴, Redux
BLoC 패턴: BLoC(Business Logic Component) 패턴은 비즈니스 로직을 별도의 컴포넌트로 분리하여 상태를 관리하는 패턴입니다. flutter_bloc 패키지를 사용하여 BLoC 패턴을 구현할 수 있습니다.
예제:
1. pubspec.yaml에 flutter_bloc 추가
flutter:
sdk: flutter
flutter_bloc: ^7.0.0
2. BLoC 및 이벤트 정의
// 이벤트 정의
abstract class CounterEvent {}
class Increment extends CounterEvent {}
// 상태 정의
class CounterState {
final int count;
CounterState(this.count);
}
// BLoC 정의
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0));
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (event is Increment) {
yield CounterState(state.count + 1);
}
}
}
3. BLoC 패턴 사용
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (context) => CounterBloc(),
child: CounterWidget(),
),
);
}
}
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterBloc = context.read<CounterBloc>();
return Scaffold(
appBar: AppBar(
title: Text('BLoC Pattern Example'),
),
body: Center(
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('You have pushed the button this many times:'),
Text(
'${state.count}',
style: Theme.of(context).textTheme.headline4,
),
],
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => counterBloc.add(Increment()),
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Redux: Redux는 상태 관리 라이브러리로, 애플리케이션의 상태를 중앙 집중식으로 관리합니다. flutter_redux 패키지를 사용하여 Redux 패턴을 구현할 수 있습니다.
예제:
1. pubspec.yaml에 flutter_redux 추가
flutter:
sdk: flutter
flutter_redux: ^0.8.0
redux: ^4.0.0
2. Redux 상태 및 액션 정의
class AppState {
final int counter;
AppState(this.counter);
}
// 액션 정의
class IncrementAction {}
// 리듀서 정의
AppState reducer(AppState state, dynamic action) {
if (action is IncrementAction) {
return AppState(state.counter + 1);
}
return state;
}
3. Redux 패턴 사용
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'redux_state.dart';
void main() {
final store = Store<AppState>(reducer, initialState: AppState(0));
runApp(MyApp(store));
}
class MyApp extends StatelessWidget {
final Store<AppState> store;
MyApp(this.store);
@override
Widget build(BuildContext context) {
return StoreProvider(
store: store,
child: MaterialApp(
home: CounterWidget(),
),
);
}
}
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Redux Example'),
),
body: Center(
child:
'프로그래밍 > Flutter' 카테고리의 다른 글
[Flutter] 7. Flutter의 "내비게이션 및 라우팅" (0) | 2024.06.26 |
---|---|
[Flutter] 6. Flutter의 "네트워킹 및 데이터 처리" (0) | 2024.06.26 |
[Flutter] 4. Flutter의 "기본 위젯 사용" (0) | 2024.06.23 |
[Flutter] 3. Flutter의 "레이아웃 및 UI 구성" (0) | 2024.06.21 |
[Flutter] 2. Flutter의 "기본 개념" (0) | 2024.06.21 |