flutter에서 provider와 consumer를 언제 사용해야할지, 두개의 차이점이 무엇인지 궁금했다.
Provider는 데이터를 전달해주는 역할을 한다.
Consumer는 2가지 상황에서 provider 대신에 사용된다.
1. Provider의 자손인 BuildContext를 가지고 있지 않아서 Provider.of를 사용할 수 없을 때, Provider에서 값을 얻을 수 있게 한다.
document에서 이렇게 말하는데, 이게 무슨 말이지 헷갈릴 것이다...
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => Foo(),
child: Text(Provider.of<Foo>(context).value),
);
}
다음의 상황처럼, provider를 생성 했는데, 소비해야할 때 나타난다.
위의 코드는 Provider.of가 BuildContext와 함께 불러졌기 때문에 ProviderNotFoundException 에러가 날 것이다.
이 때 Consumer widget을 사용한다.
이렇게!!
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => Foo(),
child: Consumer<Foo>(
builder: (_, foo, __) => Text(foo.value),
},
);
}
Consumer를 사용하면 ProviderNotFoundException 에러가 나지 않을 것이다.
2. 전체 위젯을 rebuild 하지 않고, 업데이트가 필요한 widget만 rebuild 함으로서 Provider 보다 성능을 더 높일 수 있다.
만약 Provider.of에서 listen:true로 설정하면 관련 위젯들은 Provider의 값이 바뀔때마다 rebuild 될 것이다.
따라서 굳이 필요없는 rebuild를 계속 하게 될 수도 있다.
예를 들면,
@override
Widget build(BuildContext context) {
return FooWidget(
child: BarWidget(
bar: Provider.of<Bar>(context),
),
);
}
다음의 코드에서는 BarWidget만 Provider.of의 리턴값에따라 달라진다. 하지만 Bar가 변하면 BarWidget과 FooWidget이 모두 rebuild 될 것이다.
이상적으로는 BarWidget만 rebuild 되면 된다.
이때 Consumer를 사용하는 것이다.
@override
Widget build(BuildContext context) {
return FooWidget(
child: Consumer<Bar>(
builder: (_, bar, __) => BarWidget(bar: bar),
),
);
}
관련된 widget인 BarWidget만 Consumer로 래핑해준다.
만약 Bar가 업데이트되면, BarWidget만 rebuild 될 것이다.
그렇다면 아래 코드와 같이 만약 FooWidget만 provider와 관련되어있다면 어떻게 해야할까?
@override
Widget build(BuildContext context) {
return FooWidget(
foo: Provider.of<Foo>(context),
child: BarWidget(),
);
}
이때도 Consumer를 사용할 수 있고, optional child argument를 사용해서 해결 할 수 있다.
@override
Widget build(BuildContext context) {
return Consumer<Foo>(
builder: (_, foo, child) => FooWidget(foo: foo, child: child),
child: BarWidget(),
);
}
BarWidget이 builder의 바깥쪽에서 만들어졌다.
그리고 BarWidget instance가 마지막 파라미터로서 builder로 전달되었다.
이 의미는 builder가 새로운 값을 가지고 다시 불러졌을 때, 새로운 instance인 BarWidget은 생성되지 않을 것이다.
BarWidget을 rebuild 할 필요가 없음을 알려주므로, 만약 Foo가 변하면, FooWidget만 rebuild 될 것이다.
'flutter' 카테고리의 다른 글
TypeError: Router.use() requires a middleware function but got a undefined (0) | 2022.07.20 |
---|---|
Flask vs Django vs NodeJs (0) | 2022.06.29 |
flutter dependencies vs dev dependencies (0) | 2022.06.24 |
flutter statelesswidget class key, const란? (0) | 2022.06.23 |
flutter listview builder scroll (0) | 2022.06.22 |