[Flutter 디코딩 하기 시리즈] 2. Life of a Widget?!

ricky_0_k·2023년 3월 20일
0

서론

으 제일 보기 힘든 거 나왔다...
어느 플랫폼에서나 생명주기는 중요한 개념이니 빠르게 훑어보자

소개

https://youtu.be/cyFM2emjbQ8?list=PLjxrf2q8roU1fRV40Ec8200rX6OuQkmnl

플랫폼에는 화면 역할을 하는 기능이 있고

크게 보면 Android 에서는 Activity, iOS 는 UIViewController 이다.
Flutter 에서는 Widget 이 가장 비슷한 역할을 한다.

Flutter 는 위젯을 이용해, 화면에 그릴 것을 결정하기 때문이다.

Android 와 iOS 에서는 각 기능이 고유한 수명 주기를 가지고 있다.
onCreate, willFinishLaunchingWithOptions 을 본다면 이해하는 사람들도 있을 것이다.

Flutter 는 어떨까? 영상에서 저자는 Widget 에는 생명주기가 없다 고 한다

응? 그러면 그렇게 오늘 글은 끝? 당연히 아니다
위젯의 정의를 좀 더 깊게 알아볼 필요가 있다.

케이크 와 Widget 의 유사성

여기서도 또 비유법이 나온다. 갑자기 층마다 맛이 다른 레이어 케이크가 나온다.
케잌을 만들 때 당연히 순서가 있을 것이고, 구체적인 지시사항이 있다면 따라야 한다.
이는 만드는 도중이라도 변경되지 않는 내용이다.

여기서 맛이 예상보다 별로였다면, 우리는 어떻게 해야할까?

(또 뵙네요?) 일단 화가 나겠지만 참고... 다음에 케이크를 어떻게 만들지를 고민할 것이다.
밍밍했다면 더 강한 단 맛의 설탕을 사용할 것이고, 다른 맛을 첨가할 수도 있다.

위젯도 마찬가지이다. 각 위젯에 순서가 있고, 각 순서에 필수적인 구현사항이 있다면 따라야 한다.
그렇게 만들어진 앱은 변경이 불가한 것도 케이크 개념과 유사하다.

(결론을 빠르게 찾는 사람들을 위해), 그렇게 케이크와 Flutter 의 유사점은 아래와 같다.

  • Widget 구현에 순서가 있다.
  • 각 Widget 에 지시사항 ( = 필수 구현사항) 을 따라야 한다
  • 생성된 앱은 변경이 불가능하다.

케이크 와 Widget 의 차이

그런데 앱에서는 사용자 입력 등을 통해 Widget 을 변경할 수는 있다.
(이게 불가능하다고 생각하지 말자. 이게 안된다면 우리는 번호를 눌러 전화를 할 수 없다.)

Flutter 에서는 이걸 어떻게 처리할까?
케이크 전체! 즉 생성된 앱을 다시 만드는 방식으로 처리한다.
앱에 변화가 필요할 때 Flutter 에 새로운 위젯 모음을 전달한다

굉장히 큰 작업처럼 보이지만 Flutter 는 이를 잘할 수 있도록 설계되었다고 한다.

  • 다양한 element, render 객체들은, 위젯과 관련하여 위치를 계속 추적해 나감
  • 상태에 따라 재구성이 필요한지 체크함
  • 필요한 경우 화면 업데이트도 수행

Widget 의 수명

다시 돌아왔다. 그래서 Widget 에는 수명이 있나?

그렇지 않다고 한다.
앱에서 위젯이 생성되기도 하고 전혀 사용되지도 않다고 하며 자세한 건 flutter.dev 를 보라고 한다.
그리고 진짜 끝이다.

아 하긴 외국 사람이지... 하라는 데로 flutter.dev 도 좀 보자...

1. State

먼저 Widget 의 생명주기를 이해하려면 State 개념을 먼저 알아야 한다.
State 는 말 그대로 상태이다. 상태의 예는 여러가지가 있다.

  • 텍스트 내용
  • 글자 크기 및 색상
  • 클릭 이벤트

위 내용 이외에도 많은 것들이 있을 것이고, 뭉뚱그려 각 위젯이 가질 수 모든 있는 것들을 상태라 볼 수 있다.
Flutter 는 선언형으로 Widget 을 구성하므로 이 특징이 더 두드러진다.
선언형이 뭔가요? 싶으면 잘 쓴 글은 아니지만 여기를 참고해보자 (앞 광고 굿)

종류

공식 문서를 보니 이것도 종류가 있는 듯 하다. 크게는 이렇게 이야기할 수 있다고 한다.

  1. 임시 상태 (UI 상태, 로컬 상태)
    단일 위젯에 깔끔하게 포함할 수 있는 상태

    ex

    • BottomNavigationBar에서 현재 선택된 탭
    • 애니메이션의 현재 상태
    • PageView의 현재 페이지

    StateFulWidget 및 setState 등으로 간단하게 관리 가능

  2. 앱 상태
    앱의 여러 부분에서 공유될 수 있는 상태

    ex

    • 로그인 정보
    • 소셜 네트워킹 앱의 알림
    • 커머스 앱의 장바구니

    여러 화면 또는 기능에서 불릴 수 있으므로 이를 위한 상태 관리 라이브러리가 존재함
    (bloC, provider, getX 등)

정리하다보니 중요한 개념이라는 생각이 들었다.
더불어 "어떤 상태를 사용하면될지" 는 아래 순서도를 참고하면 된다.

그 외 안티 패턴, Provider, ChangeNotifie 등에 대한 이야기도 있는데, 내용이 산으로 갈 것 같아 링크만 이야기하려 한다.

2. StatelessWidget, StatefulWidget

Flutter Widget 은 앱의 상태값을 후술할 build() 함수를 통해 그려내고, 그렇게 나온 결과물을 UI 로 보여준다.
Flutter Widget 은 위에서 이야기한 State 유무로 위젯을 크게 두 개로 분류가 가능하다.

1. StatelessWidget

State 가 없는 위젯이라고 보통 이야기한다.
하지만 개인적으로는 State 를 관리하지 않는 위젯이라고 본다.

State 가 존재하지 않아 관리할 방법이 없으므로, StatelessWidget 은 위젯 내용을 변경할 방법이 없다.
그래서 생명주기도 비교적 단순한 편이다. 만들어주고 끝이다.

1. build()

  • 위젯을 새로 그린다.
  • 위젯을 렌더링 해줄 때마다 (= 그려줄 때마다) 호출된다.
    • 위젯이 트리에 처음 삽입될 때
    • 위젯의 부모가 구성을 변경할 때
    • InheritedWidget 이 변경 사항에 종속될 때

2. StatefulWidget

이 역시 State 가 있는 위젯이라고 보통 이야기한다
하지만 개인적으로는 State 를 관리하는 위젯 이라고 본다.

관리하므로, StatefulWidget 은 위젯의 내용을 변경할 수 있다.

createState()

StatefulWidget 는 createState() 함수에 의해 별도의 State 를 생성하여 위젯을 관리한다.
그래서 해당 State 내에 Widget 생명주기 함수들이 존재한다.
build() 함수도 여기에 존재한다.

함수 종류

주기가 있으므로 StatefulWidget 에는 몇 가지 함수가 더 있다.
build() 를 이용해 위젯을 그리는 건 똑같다. 주로 마주할 함수만 이야기하고 넘어가려 한다.

1. initState()
이 개체가 트리에 처음 삽입될 때 호출된다.
각 State 내에서는 이 메서드를 맨 처음정확히 한 번 호출된다.

2. setState()
state 가 변경되었음을 State 객체에 알린다.
변경된 상태 값 내용들을 기반으로 build() 를 실행하여 현재 Widget 을 갱신해준다.

3. dispose()
이 개체가 트리에서 영구적으로 제거될 때 호출된다.
각 State 내에서는 이 메서드를 맨 나중정확히 한 번 호출된다.
initState() 의 반대이다.

기타 함수들은 여기 에 명세되어 있다.

3. Widget 은 주기로 설명이 가능한가?

1. 상태가 없는 위젯 (StatelessWidget)

상태가 없는 위젯은 주기를 어떻게 설명해야 할까?

만들어진 케익과 같은 상태인 StatelessWidget 은, 완료된 상태로 보아야 하는가? 아직 동작중인 상태로 봐야하는가?

난 이 질문에 명확한 답을 하기 어려웠다.

2. 상태가 있는 위젯 (StatefulWidget)

그나마 상태가 있는 위젯은 주기가 있다.
상태가 만들어지고, 위젯이 초기화하고, 위젯을 그리고, 위젯이 파괴되는 일련의 주기가 존재한다.


주기보다 상태로 먼저 이야기가 진행되고, 상태가 있을 경우 비로소 주기가 만들어지는 모습을 보면서
왜 Flutter Widget 을 동영상에서 애매하게 표현했는지 약간은 이해할 수 있었다.

결론

이 외에도 많은 내용들이 있었지만 다 제외하고 간단하게만 작성하였다.
GlobalKey, const, CustomWidget 적극 생성하기 등등 관심 있는 분들은 공식 문서를 더 봐도 좋을 것 같다.


사실 글을 별 생각 없이 내 주관적으로 감성적으로 썼었는데, 쓰고 난 직후 조회수를 보고 깜짝 놀랐다.
이럴 줄 알았으면 좀 더 노력해서 쓸 걸 하는 아쉬움이 있다.
추후 이 시리즈를 마치게 되면 이 포스트 내용은 필히 보강해야겠다 😅

참고

profile
valuable 을 추구하려 노력하는 개발자

0개의 댓글