[flutter] 어렵기만 했던 상태관리 패키지 provider 뿌시기- 1
provider란?
- 상태를 관리하는 툴!
- 플러터에서는 상태를 관리하는 여러가지 방법이 있지만, 공식적으로 지원하는 패키지는 존재하지 않으며 다양한 패키지 중에 사용자가 가장 많은 패키지이다.
프로바이더를 왜 사용하는지
- 플러터는 리액트와 비슷한 형태로 렌더링 되는데, 이 과정에서 데이터를 전달하기 위해 중간에 필요없는 위젯이 생기는 현상이 발생할 수 있다. -> 이를 막기위해 프로바이더를 써서 전역에서 데이터를 관리해준다.
프로바이더의 역할
- 위젯에서 필요한 데이터에 쉽게 접근할 수 있다.
- 데이터가 변하면 UI를 다시 그린다.
- 위젯에 데이터를 전달해서 데이터가 변하면 UI를 다시 그린다. -> 비즈니스 로직을 분리할 수 있다.
- 프로바이더 자체를 위젯으로 사용한다!
Provider
- App의 최상단에 선언 후 데이터가 필요한 위젯에서 호출해서 사용함.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//materialApp을 provider로 감싸줬다.
return Provider<Dog>(create: (context)=> Dog(name:'happy',breed:'Pomeranian',age:1),
child:
MaterialApp(
title: 'Provider 02',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
)
);
}
}
//다른 위젯에서 프로바이더를 호출했다.
class BreedAndAge extends StatelessWidget {
const BreedAndAge({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Column(
children: [
Text(
'- breed: ${Provider.of<Dog>(context).breed}',
style: TextStyle(fontSize: 20.0),
),
SizedBox(height: 10.0),
Age(),
],
);
}
}
ChangeNotifier
- 위젯에 listen값을 알려줌!
-listen이 true면 위젯을 새로 그려줌. - UI를 새로 그려줄 필요가 없으면 listen을 false로 해줘야함.
(ex.버튼) - addListener로 콜백함수를 실행할 수 있음.
-> 추가된 리스너는 dispose를 수동으로 꼭 해줘야함.
(자동으로 사라지지 않음)
//models/dog.dart
class Dog with ChangeNotifier {
final String name;
final String breed;
int age;
Dog({
required this.name,
required this.breed,
this.age = 1,
});
void grow() {
age++;
notifyListeners();
print('age:$age');
}
}
//main.dart
//dog클래스를 불러와서 값을 초기화해준뒤 사용함.
//init과 dispose를 통해 리스너를 추가해주고 삭제함.
class _MyHomePageState extends State<MyHomePage> {
final dog = Dog(name: 'cando', breed: 'breed03');
void initState() {
super.initState();
dog.addListener(dogListener);
}
void dogListener() {
print('age listener:${dog.age}');
}
void dispose() {
dog.removeListener(dogListener);
super.dispose();
}
ChangeNotifierProvider
- changeNotifier 인스턴스를 만들어서 프로바이더로 인스턴스에 쉽게 접근하기!
Provider.of<T>(context)
를 통해 필요한 데이터에 쉽게 접근하고 ui를 리빌드함.
//models/dog.dart
class Dog with ChangeNotifier {
final String name;
final String breed;
int age;
Dog({
required this.name,
required this.breed,
this.age = 1,
});
void grow() {
age++;
notifyListeners();
}
}
//main.dart
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return ChangeNotifierProvider<Dog>(
create: (context)=> Dog(name:'hey',breed:'mumI'),
//child하위의 widget은 모두 provider에 접근 가능함
child: MaterialApp(
title: 'Provider 04',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
),
);
}
}
class BreedAndAge extends StatelessWidget {
const BreedAndAge({Key? key }) : super(key: key);
Widget build(BuildContext context) {
return Column(
children: [
//이런식으로 접근 할 수 있음!!
//리슨 설정도 가능함
Text(
'- breed: ${Provider.of<Dog>(context,listen:false).breed}',
style: TextStyle(fontSize: 20.0),
),
SizedBox(height: 10.0),
Age(),
],
);
}
}
Provider extension methods
a.k.a 프로바이더 간편하게 쓰기
- Provider.of로 시작하는 프로바이더의 옵션들을 대치어를 통해 짧게 줄일 수 있음.
- Provider 선언후 Provider.of대신 아래의 context.~~를 사용하면 됨!
context.read<T>()
- Provider.of(context,listen:false)
- listen이 false인 프로바이더에 접근할 때
ElevatedButton( //context.read<Dog>: Provider.of<Dog>(context,listen:false) onPressed: () => context.read<Dog>().grow(), child: Text( 'Grow', style: TextStyle(fontSize: 20.0), ), ),
context.watch<T>()
- Provider.of(context)
- 가장 가까운 프로바이더 값에 접근함
Text( //Provider.of<Dog>(context).name '- name: ${context.watch<Dog>().name}', style: TextStyle(fontSize: 20.0), ),
context.select<T,R>(R selector(T vlaue))
- 프로바이더의 특정 값에 접근 가능함
- context.select<Dog, String>((Dog dog) => dog.name)
- context.select<클래스,반환형> :Provider.of(context)
Text(
// context.select<클래스,반환형> :Provider.of<Dog>(context)
'- breed: ${context.select<Dog,String>((Dog dog)=> dog.breed)}',
style: TextStyle(fontSize: 20.0),
),
요 강의를 듣고 정리한 내용입니다 :)
Author And Source
이 문제에 관하여([flutter] 어렵기만 했던 상태관리 패키지 provider 뿌시기- 1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@lilys2/flutter-provider-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)