[Flutter] Stacked 패키지에서 initState가 동작을 안한다? (State에 대해서....)
2023. 3. 5. 22:24ㆍDevelopers 공간 [Shorts]/Frontend
728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew,
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter
- Module Bundler : React, Webpack, Parcel
B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS
C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight
1. What? (현상)
Stacked Package에서 제공하는 View와 ViewModel로 MVVM모델을 구축했는데, BaseViewModel 사용한 ViewModel 내의 initState()함수의 내용이 동작하지 않습니다...
더보기
-----------------------------------------------------------------------------------------------------
<Stacked Package 사용방법과 ViewModel의 종류>
- import 'package:stacked/stacked.dart';
- Provider 선언체 (ViewModel)
- 상속 ViewModel 종류 : BaseViewModel, FutureViewModel, ReactiveViewModel, StreamViewModel
- notifyListeners()사용
- Provider 사용체 (View)
- ViewModelBuilder<T>.reactive()
T는 우리가 제공하려는 ViewModel의 유형이 될 것입니다. - viewModelBuilder는 ViewModel의 인스턴스를 생성하는 콜백을 받습니다.
- notifyListeners()가 ViewModel에서 호출될 때마다 빌더는 ViewModelBuilder.reactive()인 경우 다시 빌드합니다.
- notifyListeners()를 호출할 때 다시 빌드되지 않는 ViewModelBuilder.nonreactive() 라는 다른 버전이 있습니다 .
- ViewModelBuilder<T>.reactive()
-----------------------------------------------------------------------------------------------------
2. Why? (원인)
- Stateless vs Stateful widget
- StatelessWidget : immutable(불변의) 하며, Widget 객체를 상속 받아 만듭니다.
- 위젯을 생성하고 위젯의 구성요소와 속성들이 변화하지 않습니다.
- StatefulWidgets : mutable(잘변하는)하며, 똑같이 Widget 객체를 상속 받아 만듭니다.
** 사실 StatefulWidget은 immutable하지만, 내부에 존재하는 State가 Mutable하기 때문에 mutable하다고 했습니다.- 구성(State)이 변경 될때마다 폐기하고 다시 작성되며, 변경 가능한(mutable) 위젯(State)을 다시 작성하는것은 매우 저렴합니다.
- State객체 : 위젯이 ①빌드될 때 동기적으로 읽을 수 있고 ②위젯의 생명주기 동안 변경될 수 있는 정보입니다.
- Stateless Widget은 ①만, Stateful Widget은 ①, ② 모두 해당됩니다.
- 오래 유지, 재구축(rebuild)할때 마다 폐기되지 않으므로 비용 큰 계산을 피할 수 있습니다..
- StatelessWidget : immutable(불변의) 하며, Widget 객체를 상속 받아 만듭니다.
- Stateful Widget Lifecycle(생명주기)
- createState() : StatefulWidget을 빌드하도록 지시하면 즉시 State object 객체를 생성합니다.
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
mounted == true : Background로 진행되며, createState가 state클래스를 생성하면 state가 buildContext에 할당되며, mounted가 true가 됩니다.
**mounted : object가 위젯트리 내에 있는지를 판단하는 변수 - initState() : 위젯이 생성될때 처음으로 호출되는 메서드이며, super.initState()를 호출해야합니다.
- didChangeDependencies() : "위젯이 의존하는 데이터의 객체"가 호출될때마다 호출됩니다. 즉, state가 변경되면 호출될 수 있습니다.
- build() : UI를 구현하는 부분으로, 이곳에 계산이 필요한 로직이 많이 존재하면 performance가 안좋아집니다.
@override
Widget build(){
return Container(...)
} - didUpdateWidget() : 부모 위젯이 구성이 변경되어서 다시 re-build될 때 호출됩니다. 위젯의 바뀌는 부분을 파악할 때 유용하게 쓸 수 있으며, Widget을 리턴합니다.
- setState() : 프레임워크 자체적, 또는 개발자로 부터 자주 호출되는 명령어이며, 현재 object 내부 상태가 바뀌었으니 다시 "5.build" method를 호출하라고 합니다.
onPressed: () {
setState(() { // setState() 추가.
_counter++;
});
}, deactivate(): 위젯의 state가 제거 혹은 다른 곳으로 이동될 때 호출되며, 잘 사용하지 않습니다.- dispose() : State객체가 영구히 제거될 떄 호출되며, super.dispose()와 controller 등을 .dispose() 해줄 때 사용합니다.
mounted == false : 위젯트리에서 제거된다는 의미로 mounted를 false로 할당하며, 이후 "6.setState()"가 호출되면 에러가 발생
- createState() : StatefulWidget을 빌드하도록 지시하면 즉시 State object 객체를 생성합니다.
- BaseViewModel과 View의 구현
- StackedView
- abstract class StackedVIew extends SatelessWidget
- BaseViewModel
- (stacked) class BaseViewModel extends ChangeNotifier with BuilderHelpers, BusyAndErrorStateHelper
- (flutter) class ChangeNotifier implements Listenable
- (flutter) abstract class Listenable
- (flutter) class ChangeNotifier implements Listenable
- (stacked) class BaseViewModel extends ChangeNotifier with BuilderHelpers, BusyAndErrorStateHelper
- 즉, BaseViewModel은 initState()가 없다... 물론 stateful이 아니더라도 initState를 만들 수는 있지만, 공식사이트에 의하면 initState를 @override할 수 있는 대상은 없다..
- StackedView
3. How? (해결책)
-
- BaseViewModel을 초기화할 수는 없고, 변수는 바로 생성후에 초기화하자
- 혹은 HTTP request 나 카메라 초기화 등 Future가 필요한 것들은 FutureViewModel을 사용하자
https://velog.io/@songoori/Flutter-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0
https://pub.dev/documentation/stacked/2.0.4/stacked/stacked-library.html
728x90
반응형
'Developers 공간 [Shorts] > Frontend' 카테고리의 다른 글
[Flutter] A GlobalKey was used multiple times inside one widget's child list (0) | 2023.03.06 |
---|---|
[Flutter] Conditonal 하게 Rendering하는 방법 (0) | 2023.03.05 |
[Flutter] 내부 widget이 부여받은 사이즈로 구성하는 방법 (0) | 2023.03.05 |
[Flutter] Flutter에 아이폰을 연결해주기 (0) | 2023.02.28 |
[Flutter] CocoaPods not installed or not in valid state (0) | 2023.02.24 |