이번에는 Stateful Widget이 무엇인지 정리하는 코딩셰프 Flutter 조금 매운맛 강좌를 듣고 정리하는 포스팅이다.
우선 State가 무엇인지를 알아야한다.
직역하면 상태인데, 이렇게만 알면 Flutter에서 State의 개념을 이해하기 어렵다.
Flutter에서 State는 UI가 변경되도록 영향을 미치는 데이터이다.
그래서 크게 Stateless Widget이랑 Stateful Widget으로 나누어서 볼 수 있는데,
이제 상태 변화 없는 건 Stateless를 썼었다.
그래서 이런 Stateless, Stateful Widget은 곧 Widget tree를 이룬다.
그런데 사실 Widget tree 말고 알아야 하는 tree가 2개 더 있다.
Element tree와 Render tree이다.
각 개념을 정리하면 다음과 같다.
그래서 이를 그림으로 그려서 보면
기존의 MyApp, Scaffold 등의 Widget tree에 위치한 위젯들이
어떻게 Element tree와 Render tree랑 연결되어 있는지 알 수 있다.
그림으로 그려서 보면 아래와 같다.
여기서 보면 Element tree는 Widget tree를 point하고 있는데,
이는 C언어에서의 pointer 처럼 Widget tree의 위치 정보를 가르키는 것을 의미한다.
Reload와 Rebuild의 개념은 다르다.
Reload는 어떤 프레임을 그대로 둔 채 부수적 요소들만 바꾸는 것이다.
반면, Rebuild는 그냥 새로 갈아엎는 것을 의미한다.
Flutter는 텍스트 문자만 바꾸어도 Hot reload 때문에,
build 메서드가 호출되면서 위젯 트리가 rebuild 된다.
이런 경우, 만약 element tree와 render tree까지 모두 rebuild되면 노답이다.
따라서 새로운 위젯 트리 내의 위젯 요소들 중 위치나 타입 속성 등이 일치하는 경우에는
그냥 새롭게 생긴 애한테 element tree 링크만 업데이트한다.
(즉, 새롭게 랜더링이 필요한 내용만 render tree에 알려주는 것임)
이렇게 하면 변경된 부분만 다시 그려주기 때문에 빠르게 hot reload를 할 수 있다.
Stateless 위젯의 경우 rebuild를 통해서만 새로운 state의 적용이 가능하다.
따라서 무언가를 계속 변경하고 싶으면, Stateful 위젯을 사용하면 된다.
상속, 즉 Extend 속성은 자바와 같은 객체 지향 언어에서 봐온 개념이다.
(따라서 자세하게 정리는 하지 않겠다.)
간단히 말해서 상속은 말 그대로 부모로부터 자식이 무언가를 내려받는 것을 의마하는데,
Dart에서 상속은 결국 자식 클래스가 부모 클래스의 기능을 싹 다 쓸 수 있고, 변형도 가능한 것을 말한다.
변형을 하는 경우 재정의를 통해 할 수 있고, @override
를 이용하여 재정의하면 된다.
이제 Stateless 위젯을 Stateful 위젯으로 바꾸는 방법을 정리해보자.
일단, Stateful Widget은 두개의 클래스가 결합된 구조이다.
StatefulWidget과 State 이렇게 두개의 클래스를 상속받는다.
이렇게 두 클래스를 상속받는 이유는,
StatefulWidget은 한번 생성되면 상태가 변하지 않는 성질을 가진 Widget을 상속받는 클래스라서
StatefulWidget을 상속받는 경우, Stateless 위젯처럼 상태가 변하지 않는 위젯이 된다.
따라서 StatefulWidget을 상속받은 위젯은 변하지 않는 속성을 유지하는데
여기에 State를 상속받은 위젯을 결합하여 상태를 변할 수 있도록 하는 것이다.
따라서 여기까지의 내용을 바탕으로 만약 MyApp 위젯을 Stateful 위젯으로 구현한다면,
다음과 같이 작성하면 된다.
class MyApp extends StatefulWidget{}
// 통상적으로 State class를 상속받는 애는
// StatefulWidget 상속받은 애 이름 뒤에 State 붙임
class MyAppState extends State<MyApp>{}
State 클래스는 제네릭 타입을 가지고 있다.
따라서 이 제네릭 타입을 생성할 클래스로 해주어야 한다.
이는 이전에 한 제네릭 포스팅의 Slot 예제의 개념과 같다.
만약 MyApp 위젯을 Stateful 위젯으로 구현하는 경우 다음과 같이 작성하면 된다.
class MyAppState extends State<MyApp>{
// 아래 createState method는 State 타입으로 객체 리턴하는데,
// StatefulWidget만이 올 수 있는 객체를 State 타입으로 리턴하겠다는 의미
State<StatefulWidget> createState(){
return MyAppState();
}
}
그런데 만약, Text 위젯과 같이 stateless 위젯인 애들의 값이 변화하는 경우
이를 그때그때 바꿔주려면 어떻게 하면 될까?
이때는 setState() 메서드를 사용하여 해결하면 된다.
이렇게 setState() 메서드로 표현한 위젯들은 Flutter에서 dirty라고 표현한다.
Stateful 위젯에서 메서드는 State class가 가지고 있다.
Stateful 위젯이 rebuild 되는 경우는 두가지가 있다.
1. child 위젯의 생성자를 통해서 데이터가 전달될 때
2. internal state가 바뀔 때 : 새로운 객체가 오면 그 부분만 바뀌게 된다
이렇게 이번 포스팅은 코딩셰프 Flutter 조금 매운맛 1,2강을 듣고 정리해봤다.
어제는 진짜,, 너무 할게 많아서 정리를 못했는데,,
솔직히 돌아보면 별로 한것도 없는데 하루가 너무 짧다..
하루가 딱 2시간만 더 길면 좋겠는데 말입니다,,!!ㅜ
암튼 이제 오늘은 플러터 클론 코딩 하나 따라해보고 잘 계획이다.
낼은 목요일이라 대학원 수업도 없으니, 과제 좀 하구 금요일까지 알차게 보낼 계획 🪐✨