Flutter

[Flutter] 상태 관리와 랜더링 이해하기

챎 님 2024. 12. 21. 14:49
더보기

이 포스트는 활동하는 동아리 내에서 공부한 뒤에 작성되었습니다.

이번 포스트에서는 상태 관리에 대해 알아보며, 플러터에서의 랜더링에 대해 설명해 보겠습니다.

들어가기 전, 먼저 상태 관리가 무엇인지 확인해 보겠습니다.

상태 관리는 모든 프론트엔드에서 사용되는 의미입니다.

그렇다면 자신이 개발하는 프레임워크의 상태와 상태관리를 이해하고 솔루션에 대해서 제대로 이해하는 것이 중요하겠죠.

 

Flutter 에서 상태와 상태 관리, 랜더링에 대해 알아보겠습니다.

플러터에 위젯은 몇 개가 있을까요?

 

정답은 세 개 입니다.

흔히 Stateless Widget, Stateful Widget 두 가지 위젯에 대해서 논합니다.

Stateless Widget 은 상태가 없는 위젯입니다.

Stateful Widget 은 상태가 있는 위젯입니다.

 

먼저, 위 뒤 위젯의 차이를 설명해 보겠습니다.

단순하게 글자만 출력하는 화면이 있다고 해 봅시다.

“안녕하세요잉!” 이라는 글자를 출력하는 화면이 있으면, 배경색이 바뀐다거나 글자가 바뀌지 않고 사용자의 상호작용과 별개로 아무런 효과도 없이 진행되는 화면은 상태가 없는 것이겠죠.

이를 우리는 Stateless Widget 이라고 부릅니다.

 

그렇다면 계산기 앱을 생각해 보겠습니다.

계산기 앱은 사용자의 상호작용에 따라 지속적으로 화면이 변화지만, 실제로는 랜더링이 다시 되는 위젯입니다.

이를 상태가 있는 Stateful Widget 이라고 부르는 것입니다.

 

정리해보면, Stateless 위젯은 상태가 없기 때문에 랜더링 되면 다시 화면이 랜더링 되지 않지만

Stateful 위젯은 상태가 있기 때문에 사용자에 의해서 상태가 변경되면서 함수 호출로 화면을 다시 랜더링하게 됩니다.

Flutter 에서는 모든 위젯이 트리 구조를 갖습니다.

한 화면을 다시 랜더링 하게 된다면, 하나만 랜더링 되는 것이 아닌 그 화면으로부터 모든 하위 트리 구조의 위젯이 전부 다시 랜더링 됩니다.

예를 들어 4 번 화면부터 랜더링을 하면 4 번 화면을 포함하여 그 하위인 6 번 위젯까지 랜더링이 되는 것입니다.

다시 랜더링 된다는 것은 새롭게 build 함수를 호출하여 위젯을 랜더링 하는 것이고 기존에 있던 위젯 인스턴스가 트리에서 삭제되고 새롭게 생성된 인스턴스가 메모리에 할당되어 트리에 삽입됩니다.

즉, 기존에 있던 인스턴스의 정보를 변경하는 것이 아니라 새로운 위젯을 트리에 대체함으로써 불변성을 지킵니다.

 

그렇다면 트리에서 삭제된 위젯은 어떻게 될까요?

삭제된 위젯은 메모리에 남아있다가 Garbage Collector 에 의해 메모리에서 삭제됩니다.

이런 식으로 하여금 효율적인 랜더링을 진행합니다.

 

트리 구조에서는 Stateful widget 으로만 관리하기 어려움이 있습니다.

예를 들어, 5 번 위젯과 6 번 위젯이 서로 상태를 공유하고 있다면 6 번 위젯에서 변경된 사항들은 5 번에서도 변경되어야 합니다.

이러한 경우 Stateful widget 으로만 관리하기에는 어려움이 있습니다.

그렇기에 inherited Widget 을 제공합니다.

이것은 of 메소드를 통해서 하위 트리에서 상태 변경되면 inherited 위젯 하위의 모든 트리를 다시 랜더링하게 해 주는 상태 관리 위젯입니다.

즉, 맨 위 상위 위젯인 1 번이 inherited 어야 하위 트리들의 상태 관리가 가능하며 재랜더링이 가능한 것입니다.

 

하지만 이 inherited widget 에 단점도 존재합니다.

바로 boiler flat 코드가 심합니다. 이러한 고민을 해결하기 위해 등장한 최초의 상태 관리 라이브러리가 provider 입니다.

오늘날 provider 뿐만 아니라 Riverbeds, getX,BLoC 등 많은 상태 관리 솔루션이 등장하였습니다.

상태 관리가 무엇인지 자신이 사용하는 라이브러리가 무엇인지 파악하여 정확하게 의존성을 주입해 주어야 랜더링 에러를 줄일 있습니다.