Programming-[CrossPlatform]/Flutter

Flutter 기본-7. State와 StatefulWidget

컴퓨터 탐험가 찰리 2023. 1. 18. 05:48
728x90
반응형

Youtube 코딩셰프님의 강의를 요약 정리한 글이다. dart 언어나 이론 부분은 자바와 유사하여 대부분 제외하였고, flutter 기초 위주로 정리한다.

https://www.youtube.com/@codingchef

 

코딩셰프

향후 대세가 될 플러터를 단계별로 맛있게 학습하실 수 있습니다!

www.youtube.com

 


 

1. State

 

State란 UI의 변경에 영향을 미치는 데이터라고 할 수 있다. 이제 이 State가 변함에 따라 다른 형태의 화면이 표시될 수 있는 StatefulWidget에 대해서 공부한다.

 

플러터의 위젯 트리

그 전에 플러터가 어떤 구조를 갖고 화면을 그려내는지 살펴볼 것이다. 플러터에는 Widget tree, Element tree, Render tree라는 3개의 트리가 있다.

 

  • Widget tree: 설계도. 사용자가 작성하는 코드이다.
  • Element tree: Widget tree를 기반으로 1:1 대응하여 만들어지는 tree이다.
  • Render tree: Element tree 기반으로 Render tree가 만들어지며, 실제 화면을 볼 때의 구성 요소들이다.

 

Widget Tree 요소 변경

위치나 타입 속성 등이 일치하는데 값만 바뀐 위젯이 Widget tree에 추가된다면, 그것을 바라보고 있는 Element tree는 참조 정보만 바꿔서 hot reload가 가능하게 하고 요소 변경의 비용을 최소화하도록 관리한다. 렌더 트리에서는 바뀐 부분만 다시 렌더링한다. 뒷 부분에서 예시와 함께 좀 더 자세히 이해해본다.

 

 

 

 

2. Stateful Widget

 

StatelessWidget -> StatefulWidget으로 변환하기

기본적으로 앞 장들에서 배웠던 StatelessWidget으로 카운터를 만든다. StatelessWidget 아래에 counter라는 변수를 0으로 두고, +나 - 버튼이 눌러질 때마다 onPressed 함수로 counter 값을 바꾸는 방식이다.

 

이 위젯을 StatefulWidget으로 변환해본다. 변경된 counter 변수의 값이 화면상에 다시 렌더링 될려면 StatefulWidget으로 구성되어야한다.

 

단순히 StatelessWidget을 StatefulWidget으로 변환하면 에러가 발생한다. StatefulWidget은 2개의 클래스로 구성된다. Stateless, Stateful Widget 둘 다 변화가 없는 immutable 클래스인 Widget 클래스를 상속한다. 그러나 StatefulWidget은 상태가 변해야하기 때문에 기본 골격은 immutable하게 유지하되, State 앱을 하위에 두어 상태 변화가 가능하도록 해주는 구조로 되어있다.

StatefulWidget의 부모인 Widget. 변화가 없도록 const로 immutable하게 구성된다.

 

State<T extends StatefulWidget>

mutable 위젯은 기본 StatefulWidget외에 보통 'State'라는 이름을 붙인 클래스를 추가해준다(MyApp -> MyAppState). 그리고 이 클래스는 State 클래스를 상속한다. 다음으로 State 위젯은 StatefulWidget을 상속받는 어떤 위젯을 제너릭 타입으로 받는다. 따라서 State에 상위 MyApp을 작성해주면 두 위젯이 1차적으로 연관 관계를 갖도록 만들 수 있다(아래 두 번째 사진). 이렇게하면 각 StatefulWidget을 만들 때마다 개별적인, 그러나 기능이 유사한 State 위젯을 반복적으로 만들 필요가 없다. StatefulWidget을 제너릭화함으로써 코드의 재사용성과 안정성을 높인 것이다.

State는 StatefulWidget 타입을 제네릭으로 받는다.

 

두 위젯의 State<T>를 통한 연결

createState()

이제 상위 MyApp 위젯에 State를 만들어주는 createState 메서드를 override 해준다. 이 createState 메서드는 StatefulWidget이 생성될 때마다 호출되는 메서드이다.

마지막으로 두 앱의 연결을 위해서 createState()에서 State<StatefulWidget> 타입인 MyAppState 위젯을 반환해주면 된다.

 

setState()로 완성하기

틀린 문법으로 작성한 코드이지만, 이렇게 $counter 값을 단순히 표시하도록 되어있다면 FloatingActionButton을 눌렀을 때 정상적으로 동작하지 않는다. 왜냐하면 동적으로 counter 값은 참조하고는 있지만 이것을 build를 통해서 위젯 트리를 다시 만들어서 다시 렌더링해주지는 않기 때문이다. 이럴 때 필요한 메서드가 setState 메서드이다.

 

setState 메서드를 사용하여 rebuild가 작동하도록 만든 코드는 아래와 같다. 참고로 setState()내에 사용하는 변수를 값이 변한다고 하여 dirty 라고 부른다.

 

 

 

단축 기능

위에서는 원리 학습을 위해서 직접 StatefulWidget으로 변환하였으나, 다소 번거로운 과정일 수 있다. Android Studio에서는 StatelessWidget 위에 커서를 두고, (Alt + Enter | Option + Enter)를 눌러 Convert to StatefulWidget 메뉴를 눌러주면 자동으로 변환해준다.

 

또는 애초에 stfl 이라는 약어를 입력하고 추천되는 StatefulWidget을 선택하면 StatefulWidget, createState, State의 구조를 바로 생성할 수 있다.

728x90
반응형