개요
Flutter 앱 개발 학습 초기에 위젯들을 넣는 방법을 배우다 보면 위젯들의 이름이 전부 StatelessWidget임을 알 수 있다.
그렇다면 StatefulWidget은 무엇이고 언제 쓰는걸까?
이제부터 StatefulWidget의 존재와 그 사용 방법에 대해서 알아보자.
Imperative UI (명령형) vs Declarative UI (선언형)
가장 먼저 Flutter의 UI 구성 방식에 대해서 알아보자.
UI를 짜는 방식으로는 두 가지 방식이 있다.
전통적으로 사용되어온 Imperative UI(명령형 UI)가 있고, 최근 들어 새롭게 등장한 Declarative UI(선언형 UI)로 만드는 방식이 있다.
Imperative UI (명령형 UI) 란?
전통적인 방식이라고 부를 수 있는 Imperative UI에서는 View를 '어떻게' 구성하는지를 명시한다.
'어떻게' 구성하는지에 대한게 도대체 무엇을 말하는 건지 잘 와닿지 않을 것 같기에 간단한 예시와 함께 설명을 해보겠다.
우리가 사각형을 그리고 싶은데 양 손에 무언가가 들려있어서 음성 인식 기계를 시켜서 사각형을 그리게 하는 상황을 생각해보자.▼
그래서 기계에게 사각형을 그려달라고 했는데, 사각형이 뭔지 모르는 상황이다.▼
하지만 사각형을 그려야하기에 기계에게 하나씩 명령을 한다.
아래로 선을 2cm만큼 그어라,
왼쪽으로 선을 2cm만큼 그어라,
위로 선을 2cm만큼 그어라,
오른쪽으로 2cm만큼선을 그어라.
이렇게 일련의 명령을 하고 나면 기계는 사각형을 그려준다!
하지만 이것을 다 그려도 우리가 기계에게 따로 정보를 넣어주지 않는한 기계는 이게 사각형인지 알 수가 없다.▼
이런 식으로 우리가 원하는 모양의 UI를 그리려면, 그리고자 하는 도형의 정보를 정확히 알아야한다.
원을 그리려면 원의 정의에 대해서, 원의 공식에 대해서 알아야하고 그 정보대로 기계에게 명령을 내려야 한다.
모서리가 둥근 사각형을 그리려면 모서리가 둥근 사각형의 특징에 대해 알아야하고 그 정보대로 기계에게 전달을 해야한다.
이런 식으로 정보를 정확히 전달해야하는 방식이 우리가 지금까지 써 온 전통적인 UI구성 방식이다.
Declarative UI (선언형 UI) 란?
Declarative UI 에서는 View가 '무엇을' 구성하는지를 명시한다.
역시나 '무엇을' 구성하는지의 의미가 약간 모호하기에 위의 예시를 다시 보자.▼
아까는 기계가 사각형이 무엇인지 모르는 상황이었다.
하지만 `Declarative UI` 에서는 기계가 사각형이 무엇인지 알고 있는 것이다.▼
이렇게 사각형의 정의가 무엇인지 몰라도 사용자는 사각형이 무엇인지만 대강 알아도 화면에 그릴 수 있게 되는 것이다.
우리가 타원의 모양은 알지만 타원의 방정식을 쓰라고 하면 엇 하는 경우가 많을 것인데, 타원의 방정식을 굳이 몰라도 이미 그 정보가 다 있기 때문에 우리는 타원을 명시해주기만 해도 타원의 모양을 구할 수 있게 된다.
이것이 Declarative UI 의 화면을 그리는 방식이다.
이런 Declarative UI 에는 한 가지 공식이 있다.
바로 아래의 공식인데,
$$ F(State) = View $$
하나의 진리로 통한다.
위젯 또는 함수에 인자로 State(상태)를 넘겨주게 되면, 그것을 View로 보여준다는 하나의 진리이다.
즉, Declarative UI은 커다란 골조는 이미 완성이 되어있고 그 안에 어떤 상태인지를 명시해주는 방식으로 View를 구성하는 것이다.
예를 들면, 사각형을 그린다면 이 사각형의 상태를 명시해줌으로써 사각형의 구체적인 상태를 보여주게 된다.▼
(약간 이런 느낌과도 비슷하다.)▼
프라푸치노에 13가지를 요구해도 프라푸치노는 프라푸치노다.
이렇게 보여주고 싶은 State를 요구하면 그 State를 기존에 있는 위젯이나 함수에 넣어서 View로 보여주게 된다.
그렇다면 Flutter는 어떤 형식?
우리가 지금 학습하는 Flutter는 Declarative UI 방식으로 View를 그린다.
여러가지 위젯들에 State를 넣어주는 방식으로 UI를 구성하는 것이다.
그런데 여기서 또 하나의 의문이 들게 된다.
"그러면 State는 도대체 무엇이길래 View에서 보여주고자 하는 것일까?"
State에 관하여
이번에 학습하고자 하는 StatelessWidget과 StatefulWidget 의 이름을 보면 State라는 용어가 이미 들어가있다.
그렇기에 State에 대해 알아야 두 위젯에 대해 알 수 있다는 것이다.
하지만 여기서 이런 말을 하면 '도대체 언제 본론으로 들어가는거야?' 하고 불평할 수 있겠지만,▼
대부분 이 그림을 보기도 전에 나갔을 것이다.
정확히 알기 위해서 State에서 보여주려고 하는 것인 Data부터 알아보자.
AppData & WidgetData
State에 대해 이해하기 위해서는 먼저 Data에 관한 간단한 이해가 필요하다.
우리가 사용하는 앱에는 굉장히 많은 페이지들이 존재하는데, 일반적으로 우리가 앱을 사용할 때를 돌이켜보면 앞 페이지에서 본 데이터가 다음 페이지에서도 똑같이 존재하는 것을 알 수 있다.▼
이런 데이터들을 일반적으로 상태로 표현하여 State라고 부르는데, Flutter에서는 이를 두 종류로 구분할 수 있다.
하나는 AppData, 다른 하나는 WidgetData 이다.
AppData
AppData는 정말 쉽게 말하면 앱 전반에서 사용되는 데이터다.
AppData에 변경점이 생기면 다른 페이지들에서도 이 변경된 내용을 보여줘야한다.
WidgetData
WidgetData는 이름 그대로 위젯에서 사용되는 데이터다.
WidgetData는 위젯에서만 사용되기 때문에 여기에 나오는 데이터들을 다른 페이지들에서 필수적으로 변경하지 않아도 된다.
위의 데이터들은 앱에서 꼭 보여줘야하는 것들이고, 이 요소들을 포괄적으로 State라고 할 수 있다.
즉, State라는 것은 보여주고자 하는 데이터 혹은 모습이라고 할 수 있다.
Stateless & Stateful
그럼 이제 Stateless와 Stateful을 설명하기 위한 서론이 끝났다.
그렇다면 Stateless와 Stateful은 도대체 무엇인가?
Stateless
지금까지 이용한 위젯들은 모두 Statless Widget들로 상태가 없는 위젯이다.
앞의 State의 설명들을 들었다면 알겠지만, 상태가 없다는 것은 표현할 모습이나 데이터가 없는 것이다.
정확히는 첫 모습이 보여주고자 하는 전부이고, 보여줄 다른 무언가가 없다는 것이다.
그러므로 굉장히 정적이고 처음 보여준 그대로 멈춰있다.
더더욱 쉽게 말하면 새로고침이 없는 위젯이다.
Stateful
하지만 지금부터 새롭게 알게된 위젯인 Stateful Widget은 다르다.
이름을 그대로 대충 해석하면 상태가 넘치는 위젯으로, 그냥 상태가 있는 위젯이다.
상태가 있기에 변화할 것이 있다는 의미로도 해석할 수 있다.
그러므로 동적이고 처음 보여준 모습에서 많은 부분이 바뀔 수 있다.
더더욱 쉽게 말하면 새로고침이 있는 위젯이다.
우리가 지금까지 사용한 유저 상호작용이 있는 앱들은 대부분 이런 Stateful Widget으로 제작이 되었다고 해도 무방하다.
StatefulWidget Template
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State createState() => _HomePageState();
}
class _HomePageState extends State {
CalendarFormat calenderFormat = CalendarFormat.month;
DateTime selectedDate = DateTime.now();
@override
Widget build(BuildContext context) {
return Container();
}
}
위와 같이 이런 식으로 코드 템플릿이 제작되어있고, setState라는 함수가 있어서 이 함수에 매개변수로 람다 함수를 넣어줌으로서 상태를 변화시킨 것을 적용할 수 있다.
조금 길게 이야기했는데 조금 잘라서 이야기하면,
setState() 함수의 역할은 위젯을 다시 그려주는 것.
setState(() {}) 의 매개변수는 위젯을 다시 그려주기 전에 수행할 명령어 집합 이라고 이해하면 쉽다.
마치며
용두사미꼴로 앞에서 State에 대해서 장황하게 설명했는데, 결국에는 새로고침하는 거랑 안하는 거로 설명이 끝나서 약간 아쉬웠다.
좀 더 직관적으로 설명하고 싶었는데 음… 잘 모르겠다.
그래도 Flutter와 같이 선언형 UI의 핵심적인 개념이니 잘 알아둬야 하기에 State에 대해서 다른 글도 더 봤으면 좋겠는 바람이다.
'Develop > Flutter' 카테고리의 다른 글
[Flutter][Error] M1 맥 Flutter CocoaPod 설치 오류 (0) | 2024.01.21 |
---|---|
[Flutter] 동기와 비동기 개론 (0) | 2024.01.20 |
[Flutter] 위젯을 메소드로 쪼개는 것이 왜 안좋은가? (0) | 2024.01.18 |
[Flutter] Flutter 위젯 디자인에 관하여 (0) | 2024.01.17 |
[Flutter] M1 맥북에서 Flutter 세팅하기(feat. VSCode) (11) | 2024.01.16 |