이번 글에서는 Flutter State Management 중 인기가 높은 상태 관리 방법 인 Provider에 대해서 기본적인 방법만 알아보겠다
개인적으로 상태관리 방법 중에 사용 측면에서는 배우기 가장 쉬운 상태 관리 방법이라고 생각한다
State Management에 대해서는 구글에 관련 내용이 많이 나와있어 여기서는 생략하겠다
provider는 ChangeNotifier를 상속받아 model을 만들어 주면 된다
private으로 선언된 _count를 0으로 초기화하고 외부에서 접근할 수 있게 getter를 생성해준다
Model class에 increment(), decrement(), reset() method를 만들어 준다
각각 _count 값을 1씩 올리거나, 내리거나, 초기화 하는 method이다
여기서 중요한 부분이 바로 notifyListeners(); 부분이다
notifyListeners()는 StatefulWidget의 setState((){})와 동일한 기능을 한다고 보면 된다
변경된 값을 state에 보내주는 역할을 한다
notifyListeners를 만들어 주지 않으면 상태 변경이 안된다
// getter
int get count => _count;
import 'package:flutter/material.dart';
class VelogStateProviderModel with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void decrement() {
_count--;
notifyListeners();
}
void reset() {
_count = 0;
notifyListeners();
}
}
Provider를 사용하기 위해서는 app의 어느 부분에서 사용하냐에 따라서 생성 방식에 차이가 있지만 여기서는 앱 전체가 아닌 하나의 위젯에서만 사용하기 위해 아래와 같이 코드를 작성하였다
앱 전체에 사용하고자 하면 MyApp()을 감싸서 사용하면 되고 한 개의 provider model이 아닌 여러 개의 model을 사용할 경우 MultiProvider를 사용하면 된다
ChangeNotifierProvider(create :(context) => Model()),
Provider는 생성된 자식 위젯에서 호출이 가능하고 호출 방법에도 여러 개의 방법이 있다
여기서는 Consumer를 사용했다
Consumer에는 을 선언해주고 builder 속성에 context, model, child를 사용해서 위젯에서 사용하면 된다
build(BuildContext context) {
return ChangeNotifierProvider<VelogStateProviderModel>(
create: (_) => VelogStateProviderModel(),
child: Consumer<VelogStateProviderModel>(
builder: (context, value, child) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: const Text('Provider'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
...])),
});
}
Widget
count 값은 아래와 같이 builder 속성인 value로 접근하여 값을 사용할 수 있고
_buttonForm()의 onTap에 이벤트를 생성하면 된다
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Text(
value.count.toString(),
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 50),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buttonForm(
title: '+',
onTap: () {
value.increment();
}),
_buttonForm(
title: 'Reset',
onTap: () {
value.reset();
},
fontSize: 20),
_buttonForm(
title: '-',
onTap: () =>
value.decrement(),
),
],
)
],
),