BLOC에 대한 노트

yeseul kim·2024년 8월 12일
  • different route error : providers are “scoped”. if you insert of porovider inside a route, other routes will not be able to access that provider

  • provider 와의 관계

  • type을 기준으로 WidgetTree안에서 객체를 찾는다. 타입이 같은경우 가장 가까운 객체만 접근가능하다 → 단순 State여도 class로 관리하는 이유

  • What is under the hood of BLOC ? or What is that core thing that manages the state in one place?
    STREAMS or REACTIVE approach. In general terms, data will be flowing from the BLOC to the UI or from UI to the BLOC in the form of streams. If you have never heard about streams. Read this Stack Overflow answer.

  • cubit

    • cubit
    • event 정의 없이 cubit 객체 내부에 정의된 메소드를 ui에서 직접 호출하여 state에 변화를 주는 방식
    • state
  • bloc

    • bloc
    • ui에서 직접 사용가능한 메소드를 따로 정의하지않고 event를 구독하여 발생할때마다 emit을 실행하여 state에 변화를 주는 방식
    • event
    • abstract class event를 상속하는 이벤트들을 정의, 생성자 파라미터로 이벤트 호출시 payload전달 가능
    • state
  • dependency injection

    • BlocProvider
    • cubit/bloc를 의존하는 ui 위젯 상위를 감싼다.
    • ui위젯 내부에서 cubit function 또는 state 참조하기
      —BlocProvider.of(context).state.counter —> (context,listen:true)옵션으로 state값을 구독할수 있다. 기본값은 listen:false
      —BlocProvder.of(context).increment
    • provider의 child에서 context extension으로 bloc에 접근하는 경우 상위 위젯트리에서 provider를 찾지 못하는 이슈발생 → BlocBuilder 위젯, childWidget, Builder 위젯등으로 child를 한번 감싸 해결 가능
    • blocBuilder
    • 상위에 정의된 Blocprovider를 찾기 위한 context가 필요한 경우 사용
    • builder: (context,state){return widget} 형태로 state에 간편하게 접근할 수 있다.
    • buildWhen: bool값을 리턴하여 rebuild 시점을 관리할 수 있다.
    • bloc : 해당 빌더안에서만 참조가능한 bloc 오브젝트 제공
    • setState() or markNeedsBuild() called during build. 에러
      the builder function will potentially be called many times and should be a pure function
      that returns a widget in response to the state.
      빌더 함수는 플러터 프레임워크에서 필요에 따라 추가로 호출이 가능하므로 pure function이어야 한다. 그러므로 state값 변화에 따라 한번만 실행이되어야하는 일들(페이지 이동, 다이얼로그 노출 등)은 빌더 안에서 실행되면 안된다. 이러한 행위는 BlocListener에서 실행한다.
    • blocListener
    • state 변화에 대해 한번만 호출됨. return타입 void
    • listenWhen: listner 실행 시점을 관리할 수 있다.
    • bloc : 해당 빌더안에서만 참조가능한 bloc 오브젝트 제공
    • blocConsumer
      listenr와 builder를 동시에 제공하여 nesting하지 않고 사용할 수 있다.
  • buildContext extension

    • context.watch()
    • T의 변화를 구독
      -BlocProvider.of(context) 와 동일
      -BlocBuilder<T,Tstate >와 동일
      -여러 타입의 bloc인스턴스가 필요한경우 여러겹의 BlocBuilder를 사용하는것보다 builder 위젯 안에서 여러개의 watch를 사용하는 방법이 낫다
    • context.read()
      -변화를 구독할 필요없이 그저 T의 인스턴스가 필요한 경우
      -BlocProvider.of(context,listen:true ) 와 동일
    • context.select<T,R>(R cb(T value))
      T 내부의 R값만 구독할경우
  • 인스턴스간 소통

    • cubit to cubit
    • bloc to bloc
    1. streamSubscription 사용하는 방법
      listen이 필요한 인스턴스에 생성자 파라미터로 대상 인스턴스를 받아 스트림을 구독한다
    2. blocListener
      -listener안에서 state의 변화를 구독
      - listener는 initial state를 구독하지 않음
  • BlocProvider.of() fails to find Bloc

    bloc가 제공된 동일한 컨텐스트에서는 BLOC가 제공되지 않는다. 해당 컨텍스트의 child context에서 위젯 배치

  • route

    • anonymous
      materialApp에서는 navigator.push 실행시 현재 페이지의 child로 새로운 페이지를 부여하는 것이 아닌 형제 관계로 생성하기때문에 현재 페이지에 제공되어있는 provider를 공유할 수 없다.
      이런경우 push할 페이지 위젯을 blocprovider.value 로 감싸 현재 인스턴스를 공유한다 .

      아래와 같이 앱 상단에 routes가 세팅되어있는 경우 공유할 인스턴스를 변수에 저장하여 routes마다 페이지를 provider.value로 감싸서 제공할 수있다. 이경우엔 인스턴스를 수동으로 내려줘야하기때문에 상단위젯을 statefulwidget으로 하여 dispose시에 인스턴스 cancel을 해줘야한다.

    • named

    • generated

  • observing cubits/blocs

    cubit state cycle

bloc state cycle
  • event transformer
    • event transformation : incoming event를 처리하는 다양한 방식을 적용

    • 처리 함수를 event transformer라고 한다

    • event별로 또는 앱의 모든 event에 대해 특정 transformer를 적용할 수 있다.

      현재 Bloc(v8.1)의 기본 event 처리방식은 concurrent (v7.0까지는 sequential)

    • restartable 예시 : pagination - 페이지요청이후 처리전에 다른 페이지요청이들어오면 최근요청을 실행

    • droppable 예시 : infinity scroll - 스크롤이 한계 height을 넘어 새로운 데이터를 로딩중에 새로운 스크롤 요청이 들어오면 무시

    • event 별로 transformation을 거는 경우 해당 event bucket에만 적용되고 앱단에는 기본 처리방식 또는 앱단 처리방식이 적용된다.

  • hydrated_bloc remote database사용 없이 persist storage 구현에 사용됨. 예) 쇼핑카트
  • repository provider
  • cubit vs bloc
  • state management
    • 독립된 states 예) todo항목의 현재 상태 완료/미완료
    • 계산된 states 예) 완료/미완료별 todo항목 개수
  • class state vs enum state cubit을 사용할때 단순 State의 경우 enum을 사용해 만들수 있지만 class를 사용하게되면
    • type collision을 피할 수 있다
    • equatable을 subclassing하면 동일한 state가 연속으로 generate될 경우 rebuild되지 않는다
      → 동일한 state에 대해 rebuild되기를 원한다면 equatable을 사용하지 않는다.
profile
hello, world

0개의 댓글