Search

Widget & State

Widget(μœ„μ ―)

화면에 ν‘œμ‹œλ˜λŠ” λͺ¨λ“  UI μš”μ†Œ
ν”ŒλŸ¬ν„°λŠ” μœ„μ ―μ„ μ‚¬μš©ν•˜μ—¬ λͺ¨λ°”일 μ•±, μ›Ή μ•±, λ°μŠ€ν¬ν†± μ•± 등을 κ°œλ°œν•  수 μžˆλŠ” λ‹€λͺ©μ  UI ν”„λ ˆμž„μ›Œν¬μž…λ‹ˆλ‹€. μœ„μ ―μ€ UIλ₯Ό λΉŒλ“œν•˜κ³  λ ˆμ΄μ•„μ›ƒμ„ μ •μ˜ν•˜λ©°, μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€μ˜ 각 뢀뢄을 ν‘œν˜„ν•©λ‹ˆλ‹€.

State(μƒνƒœ)

화면을 κ°±μ‹ ν•˜κΈ° μœ„ν•΄μ„œ μœ„μ ―μ—μ„œ κ΄€λ¦¬ν•˜λŠ” 데이터
μ•±μ˜ μƒνƒœλŠ” μ‚¬μš©μžμ™€μ˜ μƒν˜Έ μž‘μš©, λ°μ΄ν„°μ˜ λ³€κ²½ 등에 따라 λ³€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μƒνƒœλŠ” 주둜 StatefulWidget 클래슀 내에 μ •μ˜λ˜λ©°, ν•΄λ‹Ή 클래슀λ₯Ό 톡해 μƒνƒœλ₯Ό λ³€κ²½ν•˜κ³  관리할 수 μžˆμŠ΅λ‹ˆλ‹€.
ex) μΉ΄μš΄ν„° μ•±
β€’
+ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ ν™”λ©΄μ˜ μˆ«μžκ°€ 1μ”© μ¦κ°€ν•©λ‹ˆλ‹€.
β€’
ν™”λ©΄μ˜ μˆ«μžκ°€ κ°±μ‹ λ˜κΈ° μœ„ν•΄μ„œ ν•΄λ‹Ή μœ„μ ―μ—μ„œ 숫자λ₯Ό state 둜 κ΄€λ¦¬ν•©λ‹ˆλ‹€.

Widget Type (μœ„μ ― νƒ€μž…)

ν”ŒλŸ¬ν„°(Flutter)μ—μ„œ μœ„μ ―μ€ 크게 두 가지 νƒ€μž…μœΌλ‘œ λ‚˜λˆ„μ–΄μ§‘λ‹ˆλ‹€. - StatelessWidget - StatefulWidget

StatelessWidget

μƒνƒœκ°€ μ—†λŠ” μœ„μ ―
StatelessWidget은 μƒνƒœλ₯Ό 가지지 μ•ŠλŠ” μœ„μ ―μž…λ‹ˆλ‹€. ν•œ 번 μƒμ„±λ˜λ©΄ κ·Έ μƒνƒœκ°€ λ³€ν•˜μ§€ μ•ŠμœΌλ©°, λ³€κ²½λ˜μ§€ μ•ŠλŠ” 정적인 UIλ₯Ό κ΅¬μ„±ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λ‹¨μˆœν•œ ν…μŠ€νŠΈ ν‘œμ‹œλ‚˜ 이미지 등을 ν¬ν•¨ν•˜λŠ” 정적인 화면을 λ§Œλ“€ λ•Œ μœ μš©ν•©λ‹ˆλ‹€. StatelessWidget은 build() λ©”μ„œλ“œλ§Œμ„ κ΅¬ν˜„ν•˜κ³ , μƒνƒœ 변경이 ν•„μš”ν•˜μ§€ μ•Šμ„ λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.
class MyStatelessWidget extends StatelessWidget { Widget build(BuildContext context) { return Container( child: Text('Hello, Stateless Widget!'), ); } }
Dart
볡사

StatefulWidget

μƒνƒœλ₯Ό κ°€μ§€λŠ” μœ„μ ―
StatefulWidget은 μƒνƒœλ₯Ό 가지며, μƒνƒœμ˜ 변경에 따라 UIλ₯Ό μ—…λ°μ΄νŠΈν•  수 μžˆλŠ” μœ„μ ―μž…λ‹ˆλ‹€. μ‚¬μš©μž μž…λ ₯, 데이터 λ³€κ²½ 등에 λŒ€μ‘ν•˜μ—¬ 동적인 화면을 ꡬ성할 λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. StatefulWidget은 μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜λŠ” State 클래슀λ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€. State ν΄λž˜μŠ€λŠ” μœ„μ ―μ˜ 생λͺ…주기와 ν•¨κ»˜ λ™μž‘ν•˜μ—¬ μƒνƒœμ˜ λ³€κ²½ 및 관리λ₯Ό λ‹΄λ‹Ήν•©λ‹ˆλ‹€.
class MyWidget extends StatefulWidget { _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { int counter = 0; void incrementCounter() { setState(() { counter++; }); } Widget build(BuildContext context) { return Column( children: [ Text('Counter: $counter'), ElevatedButton( onPressed: incrementCounter, child: Text('Increment'), ), ], ); } }
Dart
볡사

Widget LifeCycle - μœ„μ ― 생λͺ…μ£ΌκΈ°

μœ„μ ―μ΄ 생성, 좜λ ₯, μ œκ±°λ˜λŠ” 일련의 κ³Όμ •
생λͺ…μ£ΌκΈ°(LifeCycle)λž€? : ν”„λ‘œκ·Έλž˜λ°μ—μ„œμ˜ 객체 λ˜λŠ” μš”μ†Œκ°€ 생성, 좜λ ₯, κ°±μ‹ , μ†Œλ©Έ λ˜λŠ” 일련의 과정을 λ§ν•©λ‹ˆλ‹€.
μœ„μ ―μ€ 크게 Stateless Widget κ³Ό Stateful Widget 으둜 λ‚˜λˆ„μ–΄ λ³Ό 수 μžˆλŠ”λ°, Stateless Widget 은 μƒνƒœκ°€ μ—†κΈ° λ•Œλ¬Έμ—, μœ„μ ―μ— λ“€μ–΄μžˆλŠ” 데이터가 λ³€κ²½λ˜μ–΄ λ‹€μ‹œ κ°±μ‹ λ˜λŠ” 일이 μ—†μŠ΅λ‹ˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— Statetless Widget 의 UI λŠ” λ‹¨μˆœνžˆ μƒμ„±λ˜κ³  좜λ ₯되기만 ν•˜μ—¬ 별닀λ₯Έ 생λͺ…μ£ΌκΈ°λ₯Ό 갖지 μ•ŠμŠ΅λ‹ˆλ‹€.
Stateful Wiget μœ„μ ―μ€ 생성뢀터 좜λ ₯ 그리고 λ‹€μ‹œ μƒνƒœμ— 따라 κ°±μ‹ λ˜λŠ” λ“±, 일련의 생λͺ…μ£ΌκΈ°λ₯Ό κ°–μŠ΅λ‹ˆλ‹€. 생λͺ… 주기의 과정을 μ‰½κ²Œ 정리해보면 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
1.
μƒνƒœ 생성
2.
μƒνƒœ μ΄ˆκΈ°ν™”
3.
μ˜μ‘΄μ— μ˜ν•œ κ°±μ‹ 
4.
UI 좜λ ₯
5.
μœ„μ ― κ°±μ‹ 
6.
μƒνƒœ κ°±μ‹ 
7.
μœ„μ ― λΉ„ν™œμ„±ν™”
8.
μœ„μ ― μ†Œλ©Έ

μœ„μ ― 생λͺ…μ£ΌκΈ° μš”μ•½

생λͺ…μ£ΌκΈ°
λ©”μ„œλ“œ
μ„€λͺ…
μƒνƒœ 생성
createState()
StatefulWidget의 μƒνƒœλ₯Ό μƒμ„±ν•˜κ³  λ°˜ν™˜
μƒνƒœ μ΄ˆκΈ°ν™”
initState()
- 1번만 호좜 - 초기 μ„€μ • 및 데이터 μš”μ²­ μž‘μ—… μˆ˜ν–‰
μ˜μ‘΄μ— μ˜ν•œ κ°±μ‹ 
didChangeDependencies()
initState() 이후에 호좜되며, ν•΄λ‹Ή StatefulWidgetμ΄λ‚˜ μƒμœ„ μœ„μ ― νŠΈλ¦¬μ—μ„œ μ˜μ‘΄μ„±μ΄ 변경될 λ•Œ 호좜
UI 좜λ ₯
build()
ν‘œμ‹œν•  μœ„μ ―(UI)λ₯Ό λ°˜ν™˜
μœ„μ ― κ°±μ‹ 
didUpdateWidget()
μœ„μ ―μ΄ μ—…λ°μ΄νŠΈλ  λ•Œ 호좜, μƒˆλ‘œμš΄ 속성과 이전 속성을 λΉ„κ΅ν•˜μ—¬ ν•„μš”ν•œ μž‘μ—…μ„ μˆ˜ν–‰
μƒνƒœ κ°±μ‹ 
setState()
- λ³€κ²½λœ μƒνƒœ 톡지 - UIλ₯Ό κ°±μ‹ 
μœ„μ ― λΉ„ν™œμ„±ν™”
deactivate()
- μœ„μ ―μ΄ νŠΈλ¦¬μ—μ„œ λ²—μ–΄λ‚˜λ©΄ 호좜 - λΉ„ν™œμ„±ν™” μƒνƒœλ‘œ μ „ν™˜
μœ„μ ― μ†Œλ©Έ
dispose()
- μœ„μ ―μ΄ 제거될 λ•Œ 호좜 - λ¦¬μ†ŒμŠ€λ₯Ό ν•΄μ œν•˜κ³  정리 μž‘μ—…μ„ μˆ˜ν–‰

μ£Όμš” 생λͺ…μ£ΌκΈ° λ©”μ†Œλ“œ

β€’
initState()
β€’
build()
β€’
setState()

initState()

StatefulWidget 의 μƒνƒœλ₯Ό μ΄ˆκΈ°ν™”ν•˜κΈ° μœ„ν•΄, μ΅œμ΄ˆμ— ν•œ 번만 ν˜ΈμΆœλ˜λŠ” λ©”μ†Œλ“œ
β€’
이 λ©”μ„œλ“œλŠ” ν•œ 번만 호좜되며, 주둜 μ΄ˆκΈ°ν™” μž‘μ—…μ΄λ‚˜ μƒνƒœ λ³€μˆ˜ μ΄ˆκΈ°ν™” 등을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.
β€’
예λ₯Ό λ“€μ–΄, νŠΉμ • 데이터λ₯Ό κ°€μ Έμ˜€κ±°λ‚˜ 초기 μƒνƒœλ₯Ό μ„€μ •ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
- μƒνƒœ μ΄ˆκΈ°ν™” 및 μ„œλ²„λ‘œμ˜ 데이터 μš”μ²­ λ“±μ˜ μ½”λ“œλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€.
void initState() { super.initState(); // μ΄ˆκΈ°ν™” μž‘μ—… μˆ˜ν–‰ // βœ… μ„œλ²„λ‘œμ˜ 데이터 μš”μ²­ }
Dart
볡사

build()

μœ„μ ―μ˜ λ ˆμ΄μ•„μ›ƒκ³Ό λ””μžμΈμ„μ„ μ •μ˜ν•˜λŠ” λ©”μ†Œλ“œ - 화면에 UI κ°€ 좜λ ₯될 λ•Œ 호좜
β€’
이 λ©”μ„œλ“œμ—μ„œλŠ” UIλ₯Ό μƒμ„±ν•˜κ³  λ°˜ν™˜ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.
β€’
build() λ©”μ„œλ“œλŠ” μƒνƒœκ°€ 변경될 λ•Œλ§ˆλ‹€ 호좜되며, λ³€κ²½λœ μƒνƒœμ— 따라 UIλ₯Ό μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.
Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('My App'), ), body: // UI ꡬ성 μš”μ†Œλ“€... ), ); }
Dart
볡사

setState()

μœ„μ ―μ˜ μƒνƒœλ₯Ό λ³€κ²½μ‹œν‚€κ³ , UIλ₯Ό 갱신을 μš”μ²­ν•˜λŠ” λ©”μ†Œλ“œ
이 λ©”μ„œλ“œ λ‚΄μ—μ„œ μƒνƒœ λ³€μˆ˜λ₯Ό λ³€κ²½ν•˜κ³ , λ³€κ²½ 후에 UIλ₯Ό μ—…λ°μ΄νŠΈν•˜κ³ μž ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.
void _updateCounter() { setState(() { _counter++; // μƒνƒœ λ³€μˆ˜ λ³€κ²½ }); }
Dart
볡사
setState() λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ μƒˆλ‘œμš΄ μƒνƒœλ‘œ μ—…λ°μ΄νŠΈλœ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ UIλ₯Ό μ—…λ°μ΄νŠΈν•˜λ©΄, FlutterλŠ” λ³€κ²½λœ μƒνƒœμ— 따라 build() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ 화면을 λ‹€μ‹œ κ·Έλ¦½λ‹ˆλ‹€.