파파비의 블로그

플러터, flutter) State란 ? 그리고 stateless, stateful widget 본문

개발/flutter

플러터, flutter) State란 ? 그리고 stateless, stateful widget

N. Dave 2020. 5. 24. 16:34
반응형

플러터에서는 state라는 개념을 사용합니다.

 

<State>

State란 무엇일까요?

State란 앱에서 사용되는 data들을 의미합니다.

 

cf)

그럼 State management는 무엇일까요?

앱에서 사용되는 data들을 관리하는 방법을 의미하겠죠?

 

아무튼,

플러터에는 State가 2개로 나누어질 수 있습니다.

App state와 Widget state입니다.

 

  - (1)App state

App state은 앱 전반에 걸쳐 사용되는 data입니다

앱 여기저기 전반적으로 다 필요하고, 한쪽에서 app state를 변경하면 다른 쪽에서도

data변경을 반영할 필요가 있겠죠? 

 

  - (2) Widget state

또 Widget state는 widget 내부에서만 사용되는 data입니다.

App state와의 차이점이라면 위젯 내부에서만 사용되니 따로 공유하거나 할 필요가 딱히 없을 것입니다.

 

자, 그러면 state를 이해했으니

StatelessWidget과 StatefulWidget을 이해해봅시다.

 

<StatelessWidget>

StatelessWidget는 말그대로 State가 없는 Widget입니다.

Data가 없다는 뜻일까요? 그것은 아닙니다.

 

'변경될 data가 없다!' 로 이해하시면 됩니다.

 

StatelessWidget위젯도 만들때는 어떻게 만들어야할지 data가 주어질 수도 있습니다. 

하지만 그것으로 끝, 내부의 data는 변경되지 않습니다.

예를 들면 화면 한 부분에 설명을 담당하는 Text위젯이나,

배경이 되는 위젯이 StatelessWidget이 될 수 있습니다. 클릭해서 어떤 반응을 기대하지도 않는 widget들 말이죠.

 

하지만 StatelessWidget도 바꿀 수 있습니다.

바꾸는 방법은 일단 StatelessWidget의 상위 위젯에 Stateful위젯이 있어야하고,

Stateful위젯에서 StatelessWidget을 build할 때, 넣는 인자값이 바뀌고, 그리고 Stateful위젯에서setstate이실행되면

값이 변했을 경우StatelessWidget은 re-build됩니다.

 

 

 

<StatefulWidget>

StatefulWidget은 State이 존재하는 Widget입니다.

그래서 내부에 data가 변경될 경우, 그에 맞게 화면을 다시 그려서 변경된 부분을 위젯에 반영할 수 있습니다.

예를 들어 어떤 점수를 나타내는 위젯의 경우 사용자가 점수를 획득하면 그에 따라 계속 업데이트를 해주어야겠죠?

이 것이 StatefulWidget입니다!.

 

 

이제 개념적으로 이해했으면,

StatelessWidget과 StatefulWidget들의 코드를 살펴봅시다.

 

<StatelessWidget DeepDive>

먼저 더 간단한 StatelessWidget에 대해서 살펴보면,

Stateless 위젯을 하나 만들어보았습니다.

Stateless의 특징은 State이 없다는 것이고, 따라서 내부의 data가 바뀔 수 없다는 것을 의미합니다.

 

그 말은 다른 말로는 내부의 data가 immutable하다는 의미이기도 하죠.

그래서 현재 TestStateLessWidget이라는 Class명에 줄이 쳐져있는데,

그 이유는 number라는 변수가 mutable하기 때문입니다. (변경이 가능하다는 얘기)

 

따라서 그 변수를 immutable하게 만들어주어야 합니다. 그러면 밑줄이 사라질 것입니다.

왜냐면 위젯자체가 Stateless하기 때문에 내부 data들도 변경이 불가능해야하기 때문입니다.

물론 무시하고 코딩을해도 되지만, 내부 data가 바뀐들 플러터는 해당 위젯을 다시 그려주지 않기 때문에

data가 바뀌어도 화면에 반영되지는 않습니다. 

 

 

이제 보면 number 변수 앞에 final이라는 키워드를 추가했고 밑줄이 사라진 것을 볼 수 있습니다.

final를 사용하여 number에 다른 값을 할당하는게 불가능해졌고, 따라서 immutable한 변수가 됐습니다.

 

StatelessWidget은 이처럼 내부의 data가 변할 수 없고, 설령 변하더라도 화면에 절대 반영되지 않습니다.

그래서 그런 존재의 위젯들은 StatelessWidget으로 해주면 됩니다.

반대로 변경 가능성이 있는 위젯들은 StatefulWidget으로 만들어야 합니다.

 

<StatefulWidget Deep Dive>

이제 StatefulWidget에 대해서 알아봅시다.

StatefulWidget의 구조는 조금 복잡합니다.

 

StatefulWidget은 2개의 클래스로 구성이 되어 있습니다.

바뀌는 부분과 바뀌지 않는 부분으로 말이죠. 

왜 그렇게 구성이 될까요?

 

위젯의 state이 바뀌고 우리가 변경된 사항을 화면에 그리라고 명령을 하면

플러터는 기존 위젯을 날려버리고 업데이트된 부분을 반영해서 위젯을 다시 그리게 됩니다.

 

다시 그릴 때, 해당 위젯을 완전히 날려버리고 다시 그린다고 하면 data도 함께 날라가 버리니까 안됩니다.

Data는 살려두고, 해당 data를 위젯에 입혀서 다시 만들어내게 됩니다.

그러면 계속해서 사라지지 않고 data를 들고 있을 class가 필요합니다.

그 class를 StatefulWidget은 가지고 있어야하기 때문에 2개의 클래스도 구성되어 있습니다.

 

이제 코드를 살펴 봅시다. 

 

위 코드에서 Test 클래스는 StatefulWidget입니다.

 

우리가 Test위젯을 생성하면 Test클래스와 연결되어 있는

_TestState 클래스에서 저장되어 있는 data를 기반으로 위젯을 만들어서 Test에 넘겨주고,

Test클래스는 넘겨받은 위젯을 우리에게 보여줍니다.

 

우리가 보게 되는 것은 Test클래스의 객체인데, 이 객체는 실은 변할 수 없는 객체입니다.

data에 변경사항이 생겨서 다시 위젯을 그리게 되면 우리에게 보여진 Test클래스의 객체는 사라지고

다시 _TestState클래스에서 변화가 반영된 data를 기반으로 위젯을 만들어서 Test에게 올려보내고

Test객체는 새로 받은 위젯을 우리에게 보여줍니다.

 

Test클래스와 _TestState는 연결되어 있어야합니다.

연결시키기 위해서는 각 클래스에 코드를 넣어주어야 합니다.

Test클래스에서는 createState 메소드를 통해 _TestState class와 연결하며

_TestState는 상속시 State<Test>를 통해 연결합니다.

(State 클래스는 제네릭 클래스입니다.)

 

 

 

 

 

 

 

 

 

 

반응형
Comments