티스토리 뷰
상태(State)란?
'상태'는 변할 수 있는 데이터이다.
이 데이터가 변할 때 화면 자체가 다시 빌드되는 것이 아닌,
데이터와 관련있는 위젯만 다시 빌드된다.
상태관리를 통해 유저는 화면이 다시 로드될 때까지 기다리지 않아도
즉시 데이터의 변화를 확인할 수 있다.
카운터 구현
카운터 UI
import 'package:flutter/material.dart';
class FirstScreen extends StatefulWidget {
const FirstScreen({super.key});
@override
State<FirstScreen> createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Counter"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'count: ',
style: TextStyle(fontSize: 25),
),
const Padding(padding: EdgeInsets.all(20)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {},
child: const Text('감소'),
),
ElevatedButton(
onPressed: () {},
child: const Text('증가'),
),
],
)
],
)),
);
}
}
StatefulWidget을 상속하는 FirstScreen 클래스와,
State를 상속하는 _FirstScreenState 클래스로 나뉘어 작성되어있다.
상태를 사용하기 위해선 StatefulWidget을 상속받아야 하고,
State 클래스를 상속받은 _FirstScreen 클래스를 통해 상태를 생성(createState)해야 한다.
상태는 _FirstScreenState(State 클래스) 안에 정의 하면 된다.
count 값 변경
int count = 0;
void increase() {
setState(() {
count += 1;
});
}
void decrease() {
setState(() {
count -= 1;
});
}
count 변수와 숫자 증감 함수를 선언해준다.
count는 0에서 시작한다.
그리고 count값은 증가와 감소라는 event가 발생할 수 있다.
증감 이벤트는 발생하면 count는 1만큼 증가하거나 감소시키고,
count는 상태이므로 이 이벤트는 상태의 변화를 발생시킨다.
children: [
ElevatedButton(
onPressed: decrease, // 함수추가
child: const Text('감소'),
),
ElevatedButton(
onPressed: increase, // 함수추가
child: const Text('증가'),
),
]
버튼의 onPressed 프로퍼티에 증감함수를 넣어준다.
위에서 함수를 선언했으므로 함수명만 넣어주면 된다.
setState()
void increase() {
count += 1;
}
이런식으로 setState() 없이 증가함수를 짠다면,
실제 count 값은 증가하지만 화면에서는 증가한 값이 반영되지 않는다.
setState() 없이 변화하는 값은 그저 변수에 불과하며,
반응성을 위해서는 setState()를 통해 값을 변경해야 한다.
Stateless & Stateful
StatelessWidget
StatelessWidget은 말그대로 상태가 없는 위젯으로,
제목이나 이미지 같이 변하지 않는 위젯들은 StatelessWidget으로 구현할 수 있다.
StatefulWidget
StatefulWidget은 상태를 포함한 위젯이다.
해당 위젯 내에서는 상태를 선언할 수 있고, 상태의 변화가 감지되었을 때
변화에 대한 이벤트를 수행한다.
import 'package:flutter/material.dart';
class StfulExample extends StatefulWidget {
const StfulExample({super.key});
@override
State<StfulExample> createState() => _StfulExampleState();
}
class _StfulExampleState extends State<StfulExample> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Container();
}
@override
void dispose() {
super.dispose();
}
}
StatefulWidget의 구조이다.
@override
State<StfulExample> createState() => _StfulExampleState();
클래스를 선언할 때 StatefulWidget을 상속받아 생성한 것을 볼 수 있다.
클래스 내에서 createState()라는 메서드를 사용해 상태를 생성한다.
class _StfulExampleState extends State<StfulExample> {
State 또한 플러터 내부에서 선언된 클래스이며
이를 상속받아 _StfulExampleState란 클래스를 만들었다.
State 클래스를 선언할 때 StfulExample에 대한 상태임을 <>에 넣어 표현해줬다.
상태 앞 _를 붙이는 것은 관례적 표현이다.
@override
void initState() {
super.initState();
}
앞서 생성한 State를 초기화하는 단계이며
필수적으로 오버라이드 해야하는 메소드는 아니다.
상태값에 대한 초기화가 필요할 때 사용하면 된다.
super.initState를 통해 부모 클래스의 initState() 메서드를 함께 실행한다.
@override
void dispose() {
super.dispose();
}
dispose()는 사용된 위젯이 사라질 때 실행되는 단계이다.
앞선 단계에서 사용하던 데이터 등을 정리할 때 쓰인다.
필수적으로 작성해야하는 메소드는 아니다.