해결된 질문
작성
·
70
1
stateful 상태관리 수업에서
store위젯을 stateless -> stateful로 바꿔 봤습니다
생성자 body에도 print()로 간단히 출력해보고
initState와 dispose도 추가해봤구요
아래 코드입니다.
import 'package:flutter/material.dart';
import 'package:flutter_app/common/product.dart';
import 'package:flutter_app/common/product_tile.dart';
class Store extends StatefulWidget { //statelessdptj -> stateful로 바꿈
Store({
super.key,
required this.cartProductList,
required this.onPressed,
}){
print(key); //추가
print(cartProductList.length); //추가
}
/// 카트에 담긴 상품 목록
final List<Product> cartProductList;
/// 클릭 이벤트
final void Function(Product product) onPressed;
@override
State<Store> createState() {
print(key);
print(cartProductList.length);
return _StoreState();
}
}
class _StoreState extends State<Store> {
@override
void initState(){ //추가
super.initState();
print("init");
}
@override
void dispose(){ //추가
print("dispose");
super.dispose();
}
@override
Widget build(BuildContext context) {
print("store build"); //추가
return Scaffold(
body: ListView.builder(
itemCount: storeProductList.length,
itemBuilder: (context, index) {
Product product = storeProductList[index];
return ProductTile(
product: product,
isInCart: widget.cartProductList.contains(product),
onPressed: widget.onPressed,
);
},
),
);
}
}
결과를 보니
버튼을 클릭할 때 마다
생성자 바디가 호출되고 있는데 , state는 build함수만 호출되고 있습니다.
제가 궁금한 것은
상태가 바뀌면 build 함수가 재실행 되는 것은 압니다
근데 지금은 store위젯과 storeState는 한 세트 아닌가요 ?
store위젯 생성자가 불린다는 것은, 새로 인스턴스 만들어 진다는 것인데
그럼 한 세트인 storeState도 매번 initState도 불려야 할 거 같은데.... 왜 그런지 알고 싶습니다.
답변 1
2
안녕하세요 유하님
StatelessWidget은 내부적으로 상태 변경이 없기 때문에 부모 위젯이 갱신될 때 부모로 부터 전달받은 상태로 새롭게 생성됩니다.
반면 StatefulWidget로 만든 Store 위젯은 가지고 있는 상태를 내부적으로 변경할 수 있기 때문에 부모 위젯의 build 함수가 실행되어도 새롭게 생성되지 않고 기존 본인 상태를 유지합니다.
만약 부모 위젯으로 부터 전달받은 매개변수가 변경되는 경우 Store 위젯의 상태도 같이 변경하고 싶다면, didUpdateWidget 함수를 이용하시면 됩니다. 링크에 예제를 만들어 두었으니 참고해 주세요.
StatefulWidget의 lifecycle 함수가 몇가지 있습니다.
initState
: Widget Tree에 추가될 때 호출되는 함수
dispose
: Widget Tree에서 제거될 때 호출되는 함수
didUpdateWidget
: 부모 위젯이 업데이트되는 경우 호출되는 함수
그 외에도 다양한 함수가 있는데, 자세한 내용은 공식 문서를 참고해 주세요.
감사합니다 🙂
부모 위젯의 build 함수가 처음 호출되느냐 그렇지 않느냐에 따라 동작이 다릅니다.
처음 부모 위젯이 build 될 때, 자식 StatefulWidget은 아직 생성되어 있지 않기 때문에 createState 함수 → initState 함수가 호출되면서 상태가 생성됩니다.
이후 부모 위젯이 build 될 때에는 자식 StatefulWidget의 상태가 이미 생성된 상태이기 때문에 createState 함수와 initState 함수는 호출되지 않고 didUpdateWidget 함수가 호출됩니다.
한 마디로 생성 → 업데이트 → 삭제 3가지 단계로 나뉜다고 이해하시면 되고, 삭제는 해당 화면을 나가서 위젯 자체가 화면에 나타나지 않을 때 dispose 함수를 호출하면서 정리된다고 이해하시면 됩니다.
관련 예제를 작성했는데 링크를 참고해 보시고, 추가로 Flutter 공식 유튜브에서 관련 내용을 설명하는 영상도 첨부 드립니다.
감사합니다 🙂
우선 라이플 사이클이랑 예제는 보고 이해했습니다!감사합니다.
선생님 그런데
검색해보니 "StatefulWidget이 생성될 때는 새로운 State 객체가 할당됩니다." 라고 뜨던데
저는 부모가 build되면 Store StatefulWidget 은 새로운 인스턴스로 생성되고 새로운 State 객체가 할당된다고 이해했습니다.
다시말해
widget 트리 상에서 삭제되었다가 새로 생성된 StatefulWidget의 주소로 대체되면서 관련메소드가 불린다고 생각했습니다.
(삭제되었다가 => dispose / 새로 생성된 StatefulWidget의 주소로 대체 => initState 가 불린다고 생각 했습니다) , 그래서 dispose 와 initState 도 불려야 하지 않나 싶었습니다
제가지금 위젯 트리 개념을 잘 이해 못하고 있는건지 ㅠㅠ 많이 헷갈리네요 ... ㅠㅠ