
Provider는 위젯에 non-widget 오브젝트를 제공하는 것이라고 할 수 있음.
만약 A Provider에서 B Provider의 값이 필요하다면?
다른 provider 값에 의존해 값을 만드는 provider.
ProxyProvider({
Key? key,
Create<R>? create,
required ProxyProviderBuilder<T,R> update,
UpdateShouldNotify<R>? updateShouldNotify,
Dispose<R>? dispose,
bool? lazy,
TransitionBuilder? builder,
Widget? child,
})
typedef ProxyProviderBuilder<T,R> = R Function(
BuildContext context,
T value,
R? previous, // create가 optional이기 때문에 Nullable
)

ProxyProvider의 update constructor를 보니
인자 2개짜리 업데이트가 인자 3개짜리 업데이트를 호출함 (..?)
typedef ProxyProviderBuilder2<T, T2, R> = R Function(
BuildContext context,
T value,
T2 value2,
R? previous,
)

ProxyProvider2의 update constructor를 보니
인자 2개짜리 업데이트가 인자 4개짜리 업데이트를 호출함 (..?)
proxyProvider0의 update 콜백에서
1. 위젯트리 상에서 A라는 오브젝트의 인스턴스를 읽어 a 변수에 저장
3. 업데이트 함수 호출 - 두번째 인자에 a 들어감
RroxyProvider)<Result>(
update: (BuildContext context, Result result){
final A a = Provider.of<A>(context);
return update(BuildContext context, A a, Result result);
}
)
proxyProvider0의 update 콜백에서
1. 위젯트리 상에서 A라는 오브젝트의 인스턴스를 읽어 a 변수에 저장
2. 위젯트리 상에서 B라는 오브젝트의 인스턴스를 읽어 b 변수에 저장
3. 업데이트 함수 호출 - 두번째 인자에 a, 세번째 인자에 b 들어감
RroxyProvider)<Result>(
update: (BuildContext context, Result result){
final A a = Provider.of<A>(context);
final B b = Provider.of<B>(context);
return update(BuildContext context, A a, B b, Result result);
}
)
ProxyProvider0를 이용하면 ProxyProvider100도 만들 수 있음
ChangeNotifierProvider(
create: (BuildContext context){
return MyChangeNotifier(myModel: Provider.of<MyModel>(context, listen: false));
},
child: ...
)
위 코드 해석
<MyModel>에 의존하는 MyChangeNotifier 만듦- create는 한번만 불리기 때문에
listen:false옵션 설정
(만약listen:false옵션을 안준다면 ? 한번 불리고 말것을 계속 listen한다는 것)- MyChangeNotifier를 만들때 다른
<MyModel>값에 의존해서 만들게 되는데<MyModel>값이 변하지 않는다면 문제가 되지 않지만<MyModel>값이 변한다면 MyChangeNotifier를 업데이트할 방법이 없음.
(만약 MyModel 값이 변하지 않는 클래스, api 콜하는 repository 같은 것이라면 문제 되지 않음)
아래 코드로 수정하여 해결 가능
ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
create: (_) => MyChangeNotifier(),
update: (_, MyModel myModel, MyChangeNotifier myChangeNotifier) =>
// 첫번째 update : ChangeNotifierProxyProvider의 property
myChangeNotifier..update(myModel), // 두번째 update: myChangeNotifier의 메서드
},
child: ...
)
update 내에서 MyModel인스턴스를 이용해 필요한 작업을 하고, 필요시 NotifyListeners() 호출
class MyChangeNotifier with ChangeNotifier{
void update(MyModel myModel){
// do some custom work based on myModel that may call NotifyListeners()
}
}