StatelessWidget과 StatefulWidget의 차이점

떨림에 무국적 위젯그리고 스테이트풀 위젯둘 다 위젯을 만드는 방법을 지시하는 클래스입니다.

무국적 위젯그리고 스테이트풀 위젯 차이점은 다음과 같습니다.

◎ 상태 비저장 위젯

일단 생성되면 상태가 변경되지 않는 불변 위젯을 나타냅니다. 즉, Widget의 내부 상태는 생성된 후에 변경할 수 없으므로 View는 상태가 변경될 때 새 Widget을 생성하고 업데이트합니다. StatelessWidget은 간단한 정적 보기를 만드는 데 사용됩니다.

스테이트풀 위젯
상태가 변경될 수 있는 위젯을 나타냅니다. 상태 객체는 위젯이 생성될 때 생성되며 상태 객체는 위젯의 수명 동안 상태를 유지합니다. 상태가 변경될 때마다 위젯은 setState() 함수를 호출하여 변경된 상태를 알립니다. 그런 다음 Flutter 프레임워크는 위젯의 build() 함수를 호출하여 변경된 상태를 반영합니다. StatefulWidgets는 사용자 입력에 따라 동적으로 변경되는 위젯을 만드는 데 사용됩니다.

※ 따라서 단순 Static View 생성시 StatelessWidget, Dynamic View 생성시 StatefulWidget 사용을 권장합니다.

StatefulWidget 수명 주기

  1. createState(): StatefulWidget에 대한 State 객체를 생성합니다.
  2. initState(): State 객체가 생성된 직후에 호출되어 상태를 초기화합니다.
  3. didChangeDependencies(): 상태 개체에 종속성이 있을 때마다 호출됩니다.
  4. build(): 위젯의 모양을 빌드합니다. 이 메서드는 StatefulWidget과 StatelessWidget 모두에서 구현됩니다.
  5. setState(): 상태 개체가 업데이트될 때 호출됩니다.
  6. didUpdateWidget(): 위젯의 구성이 업데이트될 때 호출됩니다.
  7. deactivate(): State 객체가 더 이상 필요하지 않을 때 호출됩니다.
  8. dispose(): State 개체가 삭제될 때 호출됩니다.

샘플 코드는 다음과 같습니다.

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int _counter = 0;

  @override
  void initState() {
    super.initState();
    print("initState called");
  }

  @override
  void didUpdateWidget(MyWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget called");
  }

  @override
  Widget build(BuildContext context) {
    print("build called");
    return Scaffold(
      appBar: AppBar(
        title: Text("My Widget"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: (
            Text("$_counter"),
            RaisedButton(
              child: Text("Increment"),
              onPressed: () {
                setState(() {
                  _counter++;
                });
              },
            )
          ),
        ),
      ),
    );
  }

  @override
  void deactivate() {
    super.deactivate();
    print("deactivate called");
  }

  @override
  void dispose() {
    super.dispose();
    print("dispose called");
  }
}