Provider

소밍·2023년 9월 4일
0
post-thumbnail

provider

what is state management

  • dependency injection
  • 위젯에서 필요한 데이터를 쉽게 액세스
  • synchromizing data and ui
  • 변한 데이터에 맞춰 ui를 다시 그리기

provider는 ui에 영향을 미치는 data, 즉 state를 핸들링하는 특정한 방법을 강요하지 않음
flutter bloc, flutter redux는 dependency injection 방법 외에 state를 다루는 특정한 방법을 제시하고 개발자가 그 방법을 따를 것을 제안함.
provider는 state를 핸들링할 수 있는 수단을 제공할 , state를 어떻게 핸들링하라는 방법론을 제공하지 않음.
비즈니스 로직을 ui와 분리했다 = BLOC (Business LOgic Component)

  • provider는 그 자체가 위젯임, 때문에 위제트리 상에 아무곳에나 provider를 띄울 수 있다는 것.
  • 하지만 상위 위젯에서는 해당 값 접근할 수 없음

provider constructor

Provider({
    Key? key,
    required Create<T> create, // 유일한 required 속성
    Dispose<T>? dispose,
    bool? Lazy,
    TransittionBuilder? builder,
    Widget? child
})

create 프로퍼티에서 위젯이 필요로하는 클래스의 인스턴스를 만듦
create에 전달된 함수가 리턴하는 오브젝트를 provider 하위 위젯들은 접근할 수 있음

provider에는 of라는 static 함수 있음
이 of함수에 찾고자하는 인스턴스의 타입을 줘야함
Provider.of<Dog>(context) Dog 클래스의 인스턴스를 제공
Dog이라는 타입을 브라켓 안에 표시 , provider가 위젯트리를 타고 올라가면서 인스턴스를 찾음.
'위젯트리를 타고 올라가면서 Dog타입의 인스턴스를 찾으면 나에게 달라는 것'

같은 타입의 인스턴스가 위젯트리 상에 두개가 있다면?

프로바이더는 위젯트리 상에서 나에게 제일 가까운 것을 줌,
더 먼데 있는 건 프로바이더를 통해 액세스 할 수 없음


changeNotifier 클래스

A class that can be extended or mixed in that provides a change notification API using VoidCallback for notification
플러터 위젯들은 changeNotifier를 extend하거나 ChangeNotifier를 mixin한 오브젝트 인스턴스를 리슨할 수 있음

notifyListeners

  • 데이터 변경시 notifyListeners 메서드 호출하면 ChangeNotifier 클래스를 리스닝하고 있는 모든 위젯에게 데이터 변경 사실을 알릴 수 있음.

addListener & removeListener

  • changeNotifier에는 addListener란 메서드가 있는데 이 메서드를 통해 콜백함수 등록하면 changeNotifier를 리슨할 수 있음
    • addListener를 사용해 데이터 변경사항을 관심있는 위젯에게 알려줄 수 있지만, 실제 UI업데이트 수행하는데는 추가작업 필요
    • addListener는 자동으로 dispose되지 않기 때문에 removeListener를 사용해 필요없는 addListener를 dispose 시켜줘야함.

단점

  1. 매번 수동으로 addListener를 등록해주어야함.
  2. 제거 역시 removeListener를 사용해서 수동으로 해주어야함.
  3. 위젯들에게 데이터를 전달해주기 위해서 인스턴스를 매번 생성자를 통해 전달해주어야함
  4. UI 리빌드도 수동으로 해결해야함.

ChangeNotifierProvider

  • ChangeNotifier + Provider
  • ChangeNotifier의 인스턴스를 만듦
    • ChangeNotifier 인스턴스를 '필요할 때' 만든다는 것. -> 이 옵션은 override 될 수 있음
    • ChangeNotifier가 필요 없어지면 자동으로 dispose
  • ChangeNotifier를 필요로 하는 위젯에 ChangeNotifier를 쉽게 액세스 할 수 있는 수단을 제공하고 필요하면 ui를 리빌드
    • constructor를 통해서 인스턴스를 전달할 필요없이 Provider.of를 통해서 ChangeNotifier의 인스턴스에 쉽게 액세스할 수 있음
    • Provider.of를 통해서 타입의 인스턴스를 액세스할 때 두가지 방법으로 액세스 할 수 있음
      • Provider.of<T>(context)를 통해 타입의 ChangeNotifier 인스턴스 변화를 리슨해서 변화가 있으면 ui를 리빌드할 수 있고
      • Provider.of<T>(context, listen: false)를 통해 ChangeNotifier의 인스턴스를 액세스만 하고 변화를 리슨하지 않음

Provider extension methods

  • provider는 buildContext를 익스텐드한 메서드를 포함
  • buildContext는 위젯트리 상에서 위젯의 위치에 대한 reference를 가지고 있는 오브젝트

context.read() -> T

  • Provider.of(context, listen: false) 와 동일
  • 타입 T 오브젝트를 찾아서 그 오브젝트를 리턴해줌
onPressed: () => Provider.of<Dog>(context, listen: false).grow(),
onPressed: () => context.read<Dog>().grow(),

context.watch() -> T

  • Provider.of(context) 대체함
  • 타입 T 오브젝트를 찾아서 그 오브젝트를 리턴해줄 뿐만 아니라 value 변화를 listen함
  • chageNotifierProvider, streamProvider, FutureProvider 부터의 value를 listen함
Provider.of<Dog>(context, listen: false).name,
context.watch<Dog>().name, 

context.select<T,R>(R selector(T value)) -> R

  • property를 많이 가지고 있는 오브젝트의 특정 property의 변화 리슨하고 싶을 때 사용
  • context.watch()는 오브젝트 값 하나만 변해도 리빌드하는데 context.select사용하면 리슨하고 싶은 것만 선별적으로 리슨할 수 잇음
Provider.of<Dog>(context, listen: false).breed,
context.select<Dog, String>((Dog dog) => dog.breed)

참고자료
https://www.youtube.com/watch?v=-3iD7f3e_SU&t=295s
https://www.youtube.com/watch?v=de6tAJS2ZG0&t=356s
https://engineering.linecorp.com/ko/blog/flutter-architecture-getx-bloc-provider

profile
생각이 길면 용기는 사라진다.

0개의 댓글

관련 채용 정보