임시 상태 와 앱 상태의 차이
https://flutter-ko.dev/docs/development/data-and-backend/state-mgmt/ephemeral-vs-app
이 문서는 앱 상태와, 임시 상태, 그리고 어떻게 플러터에서 각 상태들을 관리할 수 있는 지에 대해 소개합니다.
가장 광범위한 의미에서 앱의 상태는 앱이 실행 중일 때 메모리에 존재하는 모든 것입니다. 여기에는 앱의 애셋들, 플러터 프레임워크가 UI에 관해 들고 있는 모든 변수들, 애니메이션 상태, 텍스처, 글꼴 등을 포함합니다. 이 광범위한 정의는 유효하지만, 앱을 구성하는데는 그다지 유용하지 않습니다.
일단, 당신은 몇몇 상태(텍스쳐 같은)까지 관리하지는 않을 겁니다. 프레임워크가 당신을 위해 관리해줍니다. 그러니 더 유용한 상태의 정의는 “무엇이든지 언제든 UI를 재구성하기 위해 필요한 데이터” 입니다. 두번째로, 개발자가 관리하는 상태는 두 가지 개념 유형으로 분리될 수 있습니다 : 임시 상태와 앱 상태.
임시 상태
임시 상태는(가끔 UI 상태나 로컬 상태로도 불리는) 단일 위젯에 깔끔하게 포함할 수 있는 상태입니다.
이는 의도적으로 애매한 정의입니다. 여기 몇가지 예가 있습니다.
-
[PageView](https://api.flutter.dev/flutter/widgets/PageView-class.html)
에서 현재 페이지 - 복잡한 애니메이션의 현재 진행 상황
-
BottomNavigationBar
의 현재 선택된 탭
다른 부분의 위젯 트리는 이 종류의 상태에 접근이 거의 필요하지 않습니다. 이를 직렬화할 필요도 없고, 복잡한 방식들로 바꾸지 않습니다.
즉, 이 종류의 상태에는 상태관리 기술(ScopedModel, Redux 등)을 쓸 필요가 없다는 것입니다. 당신이 필요한 모든 것은 StatefulWidget
입니다.
이어지는 내용에서, bottom navigation bar의 현재 선택된 아이템이 어떻게 _MyHomepageState
클래스의 _index
멤버변수를 들고 있는지 볼 수 있습니다. 이 예제에서 _index
는 임시 상태입니다.
class MyHomepage extends StatefulWidget {
@override
_MyHomepageState createState() => _MyHomepageState();
}
class _MyHomepageState extends State<MyHomepage> {
int _index = 0;
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: _index,
onTap: (newIndex) {
setState(() {
_index = newIndex;
});
},
// ... items ...
);
}
}
보이는 것처럼, setState()
와 StatefulWidget의 상태 클래스 안에 있는 멤버 변수를 사용하는 것은 완전히 자연스럽습니다. 당신의 앱의 어떤 다른 부분도 _index
에 접근할 필요가 없습니다. 그 변수는 오직 MyHomepage
위젯 내부만을 변경합니다. 그리고 만일 사용자가 앱을 닫고 재시작하면, 당신은 _index
가 0으로 리셋되었는지 신경쓰지 않아도 됩니다.
앱 상태
임시적이지 않고 앱 여러 곳에서 재사용하려하고 사용자 세션들에 걸쳐 유지하고 싶은 세션을 우리는 어플리케이션 상태라고 부릅니다.(때로는 공유 상태라고도 부릅니다)
어플리케이션 상태의 예시들:
- 사용자 프리퍼런스
- 로그인 정보
- 소셜 네트워크 앱의 알림들
- e-commerce 앱의 쇼핑 카트
- 뉴스 앱의 기사 읽음/읽지않음 상태
앱 상태를 관리하기 위해 당신은 선택지들에 대해 알아보길 원할겁니다. 당신의 선택은 앱의 복잡성과 속성, 당신의 팀의 이전 경험 그리고 많은 다른 관점들에 달려 있습니다. 계속 읽으세요.
명확한 규칙은 없다
분명히, 앱에서 당신은 모든 상태를 State
와 setState()
를 사용하여 관리할 수 있습니다. 사실 플러터 개발진은 많은 단순한 앱 예시들(flutter create
를 실행할때마다 가져오는 스타터 앱을 포함해서)에서 이렇게 했습니다.
물론 다른 방식으로도 됩니다. 예를 들어, 특정 앱의 문맥에서 당신은 bottom navigation bar의 선택된 탭이 임시상태가 아니라고 결정할지도 모릅니다. 당신은 클래스 밖에서부터 상태를 바꿀 필요가 있을 수도 있고, 세션 사이에 상태를 유지시켜야할 수도 있습니다. 그런 경우엔 _index
변수는 앱 상태입니다.
특정 변수가 임시상태인지 앱상태인지를 구별할 명확하고 보편적인 규칙은 없습니다. 가끔은 당신은 그 중 하나를 다른 것으로 변경하기도 할 것입니다. 예를 들어 당신은 분명한 임시 상태로 시작할 테지만, 앱의 기능들이 많아짐에 따라 이는 앱 상태로 변경될 것입니다.
그런 연유로, 아래의 다이어그램을 회의적으로 잘 살펴보자 :
리액트의 setState 대 Redux의 스토어에 대해 물었을 때 Redux의 저자 Dan Abramov는 다음과 같이 대답하였습니다.
“경험의 법칙은 이것이다 : 무엇이든지 덜 어색한걸로 하라”
요약하자면, 어떤 플러터 앱이건 두가지 개념적인 상태가 있다. 임시 상태는 State
와 setState()
를 사용하여 구현할 수 있으며, 종종 단일 위젯만을 위한 것입니다. 나머지는 당신의 앱 상태입니다. 두가지 유형 모두 어떤 플러터 앱에서건 각자의 위치를 차지하며, 두 유형간의 구분은 사용자 자신의 선호도와 앱의 복잡도에 따라 달라집니다.