Stateless와 Stateful 위젯을 사용했을때 이점은 실행시 사용자에게 속도개선을 가져다 줄 뿐만 아니라 코딩하는 개발자에게도 개발속도가 개선되는 이점이 있습니다. Stateless나 Stateful없이 아래와 같이 main()에 화면을 구성하는 코딩을 바로 넣었을때는 화면을 변경하고자 할때 전체 코드를 다시 컴파일해야하는 제약이 있습니다. 아래 backgroundColor의 색상을 teal에서 red로 바꾸고 저장을 해보면 다시 컴파일 하기 전까지는 화면에 아무런 변화가 일어나지 않습니다.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.teal,
title: const Text('Title'),
),
),
),
);
}
위와 같이 코딩을 하면 변경된 코드를 적용하기 위해 앱을 재실행해야하고 이때는 처음부터 컴파일을 하기 때문에 아래 Console화면에 따르면 이 짧은 코드를 실행하는데 30초가 걸렸습니다.
Performing hot restart...
Syncing files to device AOSP on IA Emulator...
Restarted application in 3,032ms.
Hot Reload
이 코드를 아래와 같이 StatelessWidget에 넣고 main()에서는 StatelessWidget으로 선언된 클래스를 호출하도록 변경을 하면 얘기가 달라집니다.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.teal,
title: const Text('Title'),
),
),
);
}
}
처음에 컴파일 할때 한번은 마찬가지로 시간이 걸리지만, appBar의 backgroundColor를 red로 바꾸고 저장을 하면 놀라운 일이 생깁니다. 아래 콘솔을 보시면 불과 0.6초 만에 화면이 갱신되었습니다.
Performing hot reload...
Syncing files to device AOSP on IA Emulator...
Reloaded 1 of 689 libraries in 606ms (compile: 76 ms, reload: 255 ms, reassemble: 227 ms).
이 기능이 바로 Hot Reload입니다. 콘솔 옆에 번개 모양 아이콘을 눌렀을때와 같은 기능인데 Flutter가 코드를 저장할때 자동으로 번개버튼을 누르도록 해서 저장시 바로바로 화면에 적용이 되도록 만들어 주는 것 입니다.
Hot Reset
콘솔에 보면 번개모양 아이콘 옆에 이렇게 생긴 아이콘이 하나 더 있는데 이게 바로 Hot Reset입니다. Hot Reload와 다른점은 Hot Reload는 다른 변수값들은 그대로 두고 변경된 코드만 살짝 바꿔주는 반면에 Hot Reset은 변경된 코드를 적용시킴과 동시에 변수들도 초기화를 시켜준다는 것입니다. 아래 Flutter앱을 새로 만들면 제공되는 카운터 앱을 가지고 테스트를 해보겠습니다.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.teal,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
AppBar의 backgroundColor를 teal로 초기화를 하고 실행을 한뒤 “+”버튼을 눌러서 숫가를 증가시킵니다. 그 뒤에 backgroundColor를 red로 바꾸고 Hot Reload버튼을 누르면 숫자는 그대로 있고 상단바의 배경색만 빨간색으로 바뀝니다. 반면 다시 backgroundColor를 blue로 바꾸고
Hot Reset버튼을 누르면 상단바의 배경색만 파란색으로 바뀌는 것이 아니라 숫자의 값도 “0”으로 초기화가 된것을 보실수 있습니다. Hot Reset은 각종 변수값들도 초기화를 시켜주기 때문에 Hot Reload보다는 시간이 좀 걸리지만 그래도 앱을 종료하고 다시 실행시킬때 보다는 시간이 절약된다는 장점이 있습니다.
코딩할때 Hot Reload와 Hot Reset을 사용해서 더욱 속도감 있게 개발을 하기위해서 StatelessWidget과 StatefulWidget은 반드시 써야하겠습니다. 가장 자주 사용되는 4가지 레이아 Widget에 대해서 배워보도록 하겠습니다. 감사합니다.