[Flutter] Stacked 패키지에서 initState가 동작을 안한다? (State에 대해서....)

2023. 3. 5. 22:24Developers 공간 [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() 라는 다른 버전이 있습니다 .

-----------------------------------------------------------------------------------------------------

 

 


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)할때 마다 폐기되지 않으므로 비용 큰 계산을 피할 수 있습니다..
  • Stateful Widget Lifecycle(생명주기)
    1. createState() : StatefulWidget을 빌드하도록 지시하면 즉시 State object 객체를 생성합니다.
      class MyHomePage extends StatefulWidget {
        @override
        _MyHomePageState createState() => _MyHomePageState();
      }
      mounted == true : Background로 진행되며, createState가 state클래스를 생성하면 state가 buildContext에 할당되며, mounted가 true가 됩니다.
      **mounted : object가 위젯트리 내에 있는지를 판단하는 변수
    2. initState() : 위젯이 생성될때 처음으로 호출되는 메서드이며, super.initState()를 호출해야합니다.
    3. didChangeDependencies() : "위젯이 의존하는 데이터의 객체"가 호출될때마다 호출됩니다. 즉, state가 변경되면 호출될 수 있습니다.
    4. build() : UI를 구현하는 부분으로, 이곳에 계산이 필요한 로직이 많이 존재하면 performance가 안좋아집니다.
      @override
      Widget build(){
        return Container(...)
    5. didUpdateWidget() : 부모 위젯이 구성이 변경되어서 다시 re-build될 때 호출됩니다. 위젯의 바뀌는 부분을 파악할 때 유용하게 쓸 수 있으며, Widget을 리턴합니다.
    6. setState() :  프레임워크 자체적, 또는 개발자로 부터 자주 호출되는 명령어이며, 현재 object 내부 상태가 바뀌었으니 다시 "5.build" method를 호출하라고 합니다.
      onPressed: () {
                  setState(() { // setState() 추가.
                    _counter++;
                  });
                },
    7. deactivate() : 위젯의 state가 제거 혹은 다른 곳으로 이동될 때 호출되며, 잘 사용하지 않습니다.
    8. dispose() : State객체가 영구히 제거될 떄 호출되며, super.dispose()와 controller 등을 .dispose() 해줄 때 사용합니다.
      mounted == false : 위젯트리에서 제거된다는 의미로 mounted를 false로 할당하며, 이후 "6.setState()"가 호출되면 에러가 발생
  • 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
    • 즉, BaseViewModelinitState()가 없다... 물론 stateful이 아니더라도 initState를 만들 수는 있지만, 공식사이트에 의하면  initState를 @override할 수 있는 대상은 없다..

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
반응형