파파비의 블로그
플러터, flutter) List와 Stateful 위젯을 함께 쓸 때의 Problem(key의 필요성 인식) 본문
Card위젯이 있습니다.
우리는 이 Card위젯을 ListView에 column형태로 쌓아서 보여주려고 합니다.
우리는 이때 Card위젯의 배경색을 생성시 마다 랜덤하게 하여 알록달록하게 하고자 합니다.
(배경색은 State에 저장되어있다고 가정합시다)
5개가 빨 주 노 초 파 순서로 쌓여 있습니다.
이중 4번째, '초록색' card를 지웠습니다.
그러면 파란색 카드가 위로 올라가겠지요.
그런데 이상한 일이 발생합니다.
파란색 카드의 내용은 동일하지만, 색깔이 초록색으로 바뀌었습니다.
왜 그런 것일까요?
문제는 플러터가 Widget Tree와 Element Tree를 비교할 때 생기게 됩니다.
Element Tree는 Widget Tree가 다시 build 될 때,
위젯의 1) Widget Tree에서의 위치와 2) 그 위치의 Widget Type을 보고 Element Tree와 비교합니다.
그래서 혹시나 달라진 점이 있거나 or 아에 사라지면 Element Tree에서도 지우거나 변경 사항을 반영합니다.
그리고 Render Tree는 변경된 사항이 있으면 반영하여 직접화면에 그리죠.
4번째 초록색 카드를 지우게 되면 List에서는 5번째 카드가 4번째 카드의 위치로 이동하게 됩니다.
그리고 그게 Widget Tree에서도 반영이 됩니다. 따라서 4번째 카드의 위치가 비는 것이 아니라, 5번째 카드가 그 자리를 차지하게 됩니다.
따라서 5번째 파란색 카드는 Widget Tree 위치상 4번째 카드의 위치로 이동하게 되는 것이죠.
만약 Type이 달랐다면 그래도 ElementTree에서 다른 위젯임을 눈치챘을 것이지만
Type까지 똑같다보니 ElementTree에서는 변경사항을 발견하지 못해서
ElementTree에서 그대로 4번째 카드의 정보를 남겨둡니다.
특히 State위젯이다보니 State의 정보들도 그대로 보존되는데, 색깔은 State위젯에 존재해있었죠?
Stateful 위젯은 build가 실행되면, State 정보에 기반하여 객체가 다시 build됩니다.
그래서 색깔이 4번째 카드의 색깔을 갖게 된 것입니다.
5번째 카드를 가르키던 ElementTree의 정보 및 state은 어떻게 됐을까요?
5번째가 4번째 카드의 위치로 widget Tree의 포지션이 변경됐고
다른 카드가 5번째 카드의 위치로 이동하지 않았기 때문에, (왜냐면 5개가 전부였으니까)
ElementTree에서는 포지션이 비었다고 판단해서, (위젯이 지워졌다고 판단해서) 정보 및 state을 지워버리게 됩니다.
타입과 위치만으로 Element Tree와 Widget Tree를 비교하다보니 이런 문제가 발생합니다.
그래서 플러터에서는 Key라는 개념을 통해 이런 현상을 극복할 수 있습니다.
key를 사용하는 경우는 거의 이런 경우가 99%입니다.
List + Stateful 위젯.
key를 사용하는 방법?
'개발 > flutter' 카테고리의 다른 글
플러터, flutter) Gradient 사용하기 (0) | 2020.05.31 |
---|---|
플러터 위젯 및 Tree관련, Deep Dive 링크들 (0) | 2020.05.31 |
플러터, flutter) App의 LifeCycle (0) | 2020.05.28 |
플러터, flutter) Widget의 LifeCycle (0) | 2020.05.28 |
플러터, flutter) Widget Tree의 Build() 관련 최적화 (0) | 2020.05.28 |