Flutter 에는 여러가지 상태 관리 기법이 존재한다.
유명한 상태 관리 기법으로는 RiverPod, Get, Provider, BLOC 등 여러가지 상태관리 기법이 존재한다.
그렇다면 상태 관리 기법이 필요한 이유는 무엇인가??
일단 가장 큰 이유로는 실시간으로 변하는 데이터의 상태에 따라서 UI를 그려야 하는게 제일 크다고 본다.
Flutter 프로젝트를 처음 만들게 되면 뜨는 main.dart를 본 적이 있을 것이다.

import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
보게 되면 Floating Action Button으로 가운데에 있는 counter의 숫자를 늘리고 있다.
코드 중간에 보이는 StatefulWidget과 StatelessWidget이 보인다.
이것도 상태관리 기법의 한가지라고 보면 될 것 같다.
지금 StatefulWidget안을 또 살펴보면 _incrementCounter()라는 함수가 있는데 해당 함수 내부에는 setState()라는 게 또 존재한다.
간단하게 보면 그냥 _counter라는 변수를 증가시켜서 화면에서 값이 증가되는게 실시간으로 보이도록 하는게 상태관리라고 보면 좋을 것 같다.
Stateless는 정적인 상태를 관리할 수 있고 Stateful은 실시간으로 변경 사항을 적용 시켜 보여준다.
지금부터는 내가 Flutter를 지금까지 사용하는 방법이다.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePageController extends GetxController{
int counter = 0;
void incrementCounter(){
counter++;
update();
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
Get.put(MyHomePageController());
return GetBuilder<MyHomePageController>(
builder: (cont) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text(
'${cont.counter}',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: cont.incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
);
}
}
간단하게 같은 동작을 하는 코드이지만 Get상태 관리를 사용한 방법이다.
상단부분은 UI부분이고 아래에 MyHomePageController()라는 해당 페이지의 전용 GetxController를 생성해주었다.
이 pageController는 지금 위에 처럼 counter라는 변수를 초기화 하고 증가하는 함수가 있다.
다른 부분은 update(); 이 줄이 위에서 설명한 setState를 대신한다.
이제 Get상태 관리가 가지고 있는 update(); 메소드를 통해서 MyHomepageController를 보고 있는 누군가에게 counter라는 변수가 증가했다고 알려주는것이다.
그리고 원래 STF위젯으로 선언되었던 부분은 STL위젯으로 바뀌게 되었고 중간 부분에 Get.Put(MyHomePageController());
나 이 컨트롤러 쓸거야 하고 위젯(그림)을 그리는 부분인 build메소드 아래에 들어가 있다.
저거 안하고 하면 어차피 터짐.
그리고 그 바로 아래에 GetBuilder가 나오는데 나는 어떤 컨트롤러를 보고 있을 것이며 변화가 있으면 그려줄게.
이렇게 보자.
cont.counter로 Text를 그리고 있는데 GetBuilder아래에서 builder로 (cont)를 준 부분 때문에 MyHomePageController를 cont라고 부르자!!! 이런느낌이다.
그래서 cont안에 있는 counter 값이 늘어날 때마다 실시간으로 업데이트를 해주면서 UI를 다시 그려주는 것이다.
원래는 Builder를 전체 UI 상단에 거는 건 불필요한 일이다.(업데이트가 걸리면 다시 UI를 그림.)
지금처럼 TEXT만 바뀐다면 TEXT상단에만 GetBuilder로 감싸서 하게되면 부담을 줄일 수 있다.
지금은 예외로 FAB 때문에 전체를 건거니까 양해좀.
그리고 FAB를 본다면 onPressed안에 cont.incrementCounter가 들어가 있다.
말 그대로 FAB가 눌렸을 때 cont의 incrementCounter 실행해줘. 이거겠지?
(여러가지 내용이 있지만 간단하게만 하루에 한개씩 올리도록!!)