build() 는 State에 있다는 점이 포인트. setState() 로 상태를 바꾸면 build() 가 다시 그려져.class MyWidget extends StatefulWidget {
final int initialCount;
const MyWidget({super.key, this.initialCount = 0});
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with SingleTickerProviderStateMixin {
late int count;
late final AnimationController _controller;
// 1) 최초 한 번
void initState() {
super.initState();
count = widget.initialCount;
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
);
// 프레임 이후 1회 작업 (레이아웃 값 필요할 때 등)
WidgetsBinding.instance.addPostFrameCallback((_) {
// do something after first build
});
}
// 2) 상위의 InheritedWidget(예: Theme, MediaQuery) 의존이 바뀔 때
void didChangeDependencies() {
super.didChangeDependencies();
}
// 3) 부모가 새 props를 주입했을 때(동일 타입 위젯이 갱신)
void didUpdateWidget(covariant MyWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.initialCount != widget.initialCount) {
// 외부 값 변화에 반응
setState(() => count = widget.initialCount);
}
}
// 4) 그리기
Widget build(BuildContext context) {
return Row(
children: [
Text('$count'),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () => setState(() => count++),
child: const Text('증가'),
),
],
);
}
// 5) 트리에서 분리 직전(잠깐 빠졌다가 다시 붙을 수도 있음)
void deactivate() {
super.deactivate();
}
// 6) 완전 제거(리소스 정리 필수)
void dispose() {
_controller.dispose(); // controller/stream/focus 등 꼭 정리
super.dispose();
}
}
createState → initState → didChangeDependencies → build → (setState→build 반복) → didUpdateWidget(상위 변화 시) → deactivate → dispose
initStatedidChangeDependenciessetState → builddidUpdateWidgetdisposesetState(() {
// 상태값만 바꿔라 (무거운 연산 X)
count++;
});
setState 하자.if (!mounted) return; 로 위젯 생존 여부 확인!initState에서 만들고 dispose에서 정리.mounted 체크.addPostFrameCallback 사용.Key(특히 ValueKey) 로 식별자 부여.| Flutter | React |
|---|---|
StatefulWidget + State | 함수 컴포넌트 + useState/useEffect |
initState | useEffect(() => {...}, []) |
didUpdateWidget | useEffect의 deps 변화 반응 |
dispose | useEffect의 cleanup 함수 return () => {...} |
setState() | setState(...) |