Search
🎱

How to use a provider inside of another provider in Flutter

생성일
2022/03/12 03:41
태그
Flutter
속성

문제의 시작

AuthProvider ⇒ Firebase Authentication 을 활용해 인증 상태를 관리하는 Provider
UserProvider ⇒ 서비스 유저의 닉네임, 이미지 등 서비스 유저 상태를 관리하는 Provider
인증을 하면 ⇒ 인증한 사용자 정보를 가져와야 한다. 이 상황에서 Provider 간 의존성이 발생합니다.
AuthProvider 에서 인증 완료 타이밍을 UserProvider에서 catch 해야하고, AuthProvider로부터 userID를 받아와서 UserProvider는 API Server에 유저 정보를 요정해야 하는 상황입니다.
이때 사용하는게 ProxyProvider입니다. 관련되어 Google, Stack Overflow 에 많은 검색을 해봤지만 예제 코드만 존재하고, 다른 사례에 적용할 때 근거가 되는 왜? 가 부족해서 고생을 좀 했습니다.
우선 예제코드 분석,
Job, Person
`Provider` suffix를 안붙이고 쓰네요.
아래 코드를 살펴보면 Job은 Person 을 변수로 들고 있습니다. Person이 변경되면 그에 따라 Job도 변경되어야 함을 알 수 있습니다. 이것을 이해하고 ProxyProvider를 봐야합니다.
class Person with ChangeNotifier { Person({this.name, this.age}); final String name; int age; void increaseAge() { this.age++; notifyListeners(); } } class Job with ChangeNotifier { Job( this.person, { this.career, }); final Person person; String career; String get title { if (person.age >= 28) return 'Dr. ${person.name}, $career PhD'; return '${person.name}, Student'; } }
Dart
복사
다음 ProxyProvider를 사용하는 예제,
void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider<Person>(create: (_) => Person(name: 'Yohan', age: 25)), ChangeNotifierProxyProvider<Person, Job>( create: (BuildContext context) => Job(Provider.of<Person>(context, listen: false)), update: (BuildContext context, Person person, Job job) => Job(person, career: 'Vet'), ), ], child: MyApp(), ), ); }
Dart
복사
의존성이 없는 Person을 먼저 생성합니다.
그 후 Person 에 의존성이 있는 Json 을 ChangeNotifierProxyProvider 를 활용해 생성합니다.
ChangeNotifierProvider<A, A 를 의존하는 B>( create: (BuildContext context) => { B Provider 생성 }, update: (BuildContext context, A a, B b) => { 파라미터로 넘어온 A를 활용해 B를 업데이트 하는 코드 작성 } )
Dart
복사
결과물
class _AppState extends State<App> { void initState() { super.initState(); } Widget build(BuildContext context) { return MaterialApp( home: MultiProvider( providers: [ ChangeNotifierProvider<AuthProvider>(create: (_) => AuthProvider()), ChangeNotifierProxyProvider<AuthProvider, UserProvider>( create: (BuildContext context) => UserProvider(), update: (BuildContext context, AuthProvider authProvider, UserProvider userProvider) => userProvider.updateFirebaseUser(authProvider.getUser()) ) ], child: RootPage(), ) ); } }
Dart
복사