[Flutter] StatelessWidget, StatefulWidget ๐Ÿ“ฑ

dosilvยท2021๋…„ 7์›” 18์ผ
5
post-thumbnail

ํ”Œ๋Ÿฌํ„ฐ์˜ ํ•ต์‹ฌ ๊ฐœ๋…์ธ ์œ„์ ฏ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž ๐Ÿช„

๐Ÿฆ‹ Widget

ํ”Œ๋Ÿฌํ„ฐ๋ฅผ ์ฐพ๋‹ค ๋ณด๋ฉด ์ด๋Ÿฐ ํ‘œํ˜„์ด ๋‚˜์˜จ๋‹ค.

Everything is a Widget.
It's all Widgets!

์œ„์ ฏ์€ UI๋ฅผ ๋ฌ˜์‚ฌํ•˜๋Š” ๋‹คํŠธ์˜ ํด๋ž˜์Šค๋กœ์„œ, ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚  ์š”์†Œ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ์ดํ„ฐ์™€ ์„ค์ •์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. (JS๋กœ ์น˜๋ฉด ์ปดํฌ๋„ŒํŠธ์™€ ๋น„์Šทํ•œ ๊ฐœ๋…!)
์‹ค์ œ๋กœ ํ”Œ๋Ÿฌํ„ฐ์—์„œ๋Š” ๋ชจ๋“  ์š”์†Œ ํ•˜๋‚˜ํ•˜๋‚˜๊ฐ€ ์œ„์ ฏ์ด๋‹ค. ์œ„์ ฏ์ด ์œ„์ ฏ์„ ํฌํ•จํ•˜๊ณ , ์œ„์ ฏ๋“ค์ด ๋ชจ์ธ Widget Tree๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํ™”๋ฉด์„ ๊ทธ๋ฆฐ๋‹ค.

ํ™”๋ฉด์ƒ์˜ ๋ ˆ์ด์•„์›ƒ์ด๋‚˜ ์•„์ด์ฝ˜๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์Šคํƒ€์ผ, ์• ๋‹ˆ๋ฉ”์ด์…˜๊นŒ์ง€๋„ ํ”Œ๋Ÿฌํ„ฐ์—์„œ๋Š” ์œ„์ ฏ...! ๋Œ€ํ‘œ์ ์ธ ์œ„์ ฏ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๋ ˆ์ด์•„์›ƒ: Scaffold, Stack, Row, Column
  • ๊ตฌ์กฐ: Button, Toast, MenuDrawer
  • ์Šคํƒ€์ผ: TextStyle, Color
  • ์• ๋‹ˆ๋ฉ”์ด์…˜: FadeInPhoto, Transform
  • ์œ„์น˜์™€ ์ •๋ ฌ: Center, Padding

์ด ์œ„์ ฏ๋“ค์„ ๋ ˆ๊ณ ์ฒ˜๋Ÿผ ์กฐํ•ฉํ•ด์„œ ์›ํ•˜๋Š” ์•ฑ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ!
์œ„์ ฏ์€ ํฌ๊ฒŒ StatelessWidget, StatefulWidget์œผ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.



๐Ÿฆ‹ StatelessWidget

๐ŸŒˆ ํŠน์ง•

  • ์ƒํƒœ(state)๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Œ
  • ์œ„์ ฏ์„ ์–ธ์ œ ํŠธ๋ฆฌ์—์„œ ์ œ๊ฑฐํ•ด์•ผ ํ• ์ง€, ์–ธ์ œ ๋ฆฌ๋นŒ๋“œํ•ด์•ผ ํ• ์ง€๊ฐ€ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ๊ฒฐ์ •๋จ
  • ๊ฒฐ์ฝ” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ๋Š” โŒโŒ (์™ธ๋ถ€์˜ ์ •๋ณด์— ๋”ฐ๋ผ ๋ฐ˜์‘ํ•จ)

๐ŸŒˆ ๊ธฐ๋ณธ ํ˜•ํƒœ

VSC์—์„œ stl ์ž…๋ ฅ ํ›„ ์—”ํ„ฐ๋ฅผ ์น˜๋ฉด ์ž๋™์™„์„ฑ~~~๐Ÿช„ Example์ด๋ผ๊ณ  ์œ„์ ฏ ์ด๋ฆ„์„ ๋ถ™์—ฌ์ฃผ์—ˆ๋‹ค.

class Example extends StatelessWidget {
  const Example({ Key? key }) : super(key: key);

  
  Widget build(BuildContext context) {
    return Container(...);
  }
}

StatelessWidget์„ ์ƒ์†๋ฐ›๊ณ , build๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ overrideํ•œ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์Œ!

๐ŸŒท constructor(์ƒ์„ฑ์ž)

๊ธฐ๋ณธ์ƒ์„ฑ์ž๋กœ์„œ, class๋ช…(์—ฌ๊ธฐ์„œ๋Š” Example)๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง„๋‹ค. ๋’ค์— ๋ถ™์€ : super(key: key)๋Š” ๋ถ€๋ชจ์ธ StatelessWidget์˜ ๊ธฐ๋ณธ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ! ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด ๊ธฐ๋ณธ์ƒ์„ฑ์ž๋Š” ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

๐ŸŒท build

Widget์„ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๋กœ์„œ ๋ชจ๋“  ์œ„์ ฏ ํด๋ž˜์Šค์— ํฌํ•จ๋œ ํ•„์ˆ˜ ๋ฉ”์„œ๋“œ์ด๋‹ค. build๊ฐ€ ๋ฆฌํ„ดํ•˜๋Š” ์œ„์ ฏ๋“ค๋กœ ๋ทฐ๊ฐ€ ๊ทธ๋ ค์ง„๋‹ค.



๐Ÿฆ‹ StatefulWidget

๐ŸŒˆ ํŠน์ง•

  • State ๊ฐ์ฒด๋ฅผ ๊ฐ–๋Š” ์œ„์ ฏ
  • State ๊ฐ์ฒด์˜ setState ๋ฉ”์„œ๋“œ๊ฐ€ ์œ„์ ฏ์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์•Œ๋ ค์คŒ!
  • ํด๋ผ์ด์–ธํŠธ์˜ ์กฐ์ž‘์œผ๋กœ setState๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ํ”Œ๋Ÿฌํ„ฐ๊ฐ€ ์œ„์ ฏ์„ ๋‹ค์‹œ ๊ทธ๋ฆผ

๐ŸŒˆ ๊ธฐ๋ณธ ํ˜•ํƒœ

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ stf ์ž…๋ ฅ ํ›„ ์—”ํ„ฐ๋ฅผ ์น˜๋ฉด ์ž๋™์™„์„ฑ ๋˜๋Š”๋ฐ, ์ด ๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

class Example extends StatefulWidget {
  const Example({ Key? key }) : super(key: key);

  
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  
  Widget build(BuildContext context) {
    return Container(...);
  }
}

StatefulWidget์„ ์ƒ์†๋ฐ›๋Š” ์œ„์ ฏ์ด createState ๋ฉ”์„œ๋“œ๋กœ State ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๊ณ , State๋ฅผ ์ƒ์†๋ฐ›๋Š” ๊ฐ์ฒด๊ฐ€ build ๋ฉ”์„œ๋“œ๋กœ Widget์„ ๋ฆฌํ„ดํ•˜๋Š” ํ˜•ํƒœ์ด๋‹ค.

State ๊ฐ์ฒด ์ด๋ฆ„ ์•ž์— ์ž๋™์œผ๋กœ ์–ธ๋”๋ฐ”(_)๊ฐ€ ๋ถ™๋Š”๋ฐ, ๋‹คํŠธ์—์„œ ํด๋ž˜์Šค๋‚˜ ํ”„๋กœํผํ‹ฐ, ๋ฉ”์„œ๋“œ ์•ž์— ์–ธ๋”๋ฐ”๋ฅผ ๋ถ™์ด๋ฉด private์„ ์˜๋ฏธํ•œ๋‹ค. ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ ํ•ด๋‹น ํŒŒ์ผ์—์„œ๋งŒ, ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ!

๐ŸŒท setState

ํ”Œ๋Ÿฌํ„ฐ์—๊ฒŒ state๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ ค์„œ build ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜๋Š” ๋ฉ”์„œ๋“œ. ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— setState ์‹คํ–‰ ์ „ ๋ชจ๋“  ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์™„๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

์ž๋™์™„์„ฑ๋œ StatefulWidget์— setState๋Š” ์ž๋™์œผ๋กœ ๋“ค์–ด์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—... ํ”Œ๋Ÿฌํ„ฐ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ์ƒ์„ฑ๋˜๋Š” ์ดˆ๊ธฐ ์•ฑ์„ ์‚ดํŽด๋ณด์ž!

0 class MyHomePage extends StatefulWidget {
1   MyHomePage({Key? key, required this.title}) : super(key: key);
2
3   final String title;
4
5   
6   _MyHomePageState createState() => _MyHomePageState();
7 }
8
9 class _MyHomePageState extends State<MyHomePage> {
10  int _counter = 0;
11
12  void _incrementCounter() {
13    setState(() {
14      _counter++;
15    });
16  }
17
18  
19  Widget build(BuildContext context) {
20    return Scaffold(
21      appBar: AppBar(
22        title: Text(widget.title),
23      ),
24      body: Center(
25        child: Column(
26          mainAxisAlignment: MainAxisAlignment.center,
27          children: <Widget>[
28            Text(
29              'You have pushed the button this many times:',
30            ),
31            Text(
32              '$_counter',
33              style: Theme.of(context).textTheme.headline4,
34            ),
35          ],
36        ),
37      ),
38      floatingActionButton: FloatingActionButton(
39        onPressed: _incrementCounter,
40        tooltip: 'Increment',
41        child: Icon(Icons.add),
42      ),
43    );
44  }
45}
  • ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ์ƒํƒœ๊ฐ’์„ State ๊ฐ์ฒด ๋‚ด๋ถ€์— private ํ”„๋กœํผํ‹ฐ๋กœ ์ƒ์„ฑํ•ด ์ค€๋‹ค (line10)
  • setState๋ฅผ ์ด์šฉํ•ด ์ƒํƒœ ๋ณ€๊ฒฝ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค (line12)
  • ํด๋ผ์ด์–ธํŠธ์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์— ๋”ฐ๋ผ ์ƒํƒœ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ณณ์— ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ค€๋‹ค (line39)

์‚ฌ์‹ค onPressed์— ๋ฐ”๋กœ setState(() {_counter++})๋ฅผ ๋„ฃ์–ด๋„ ๋˜์ง€๋งŒ ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ๋นผ ์ค€ ๊ฒƒ ๊ฐ™๋‹น.

๐ŸŒท initState

ํ”Œ๋Ÿฌํ„ฐ๊ฐ€ ํ™”๋ฉด์— ์œ„์ ฏ์„ ๊ทธ๋ฆฌ๊ธฐ ์ „์— ํ•„์š”ํ•œ ๋ชจ๋“  ์ดˆ๊ธฐํ™”๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ



๐Ÿงš๐Ÿป Reference

Flutter Crash Course for Beginners 2021 - Build a Flutter App with Google's Flutter & Dart
๐Ÿ“• ํ”Œ๋Ÿฌํ„ฐ ์ธ ์•ก์…˜

profile
DevelOpErUN ์„ฑ์žฅ์ผ๊ธฐ๐ŸŒˆ

1๊ฐœ์˜ ๋Œ“๊ธ€