개발

flutter - BlocWidget

kwony 2022. 10. 6. 21:53

 

설명만 읽어선 이해하기 어려울 것 같아서 실제 예제 코드가 있는 https://bloclibrary.dev/#/flutterlogintutorial 페이지를 보면서 따라가면 좋을 것 같다.

 

BlocBuilder 

 

Bloc의 새로운 상태에 따라서 위젯을 만드는 클래스다. Bloc의 State가 변할 때마다 builder 함수가 여러번 불리게 되고 상태에 따라서 표현할 위젯을 바꿀 수 있다. 리턴 함수는 위젯 함수여야 한다. buildWhen 은 스테이트에 대해서 새롭게 위젯을 만들어야할지 말지를 리턴하는 함수다. 조건 문으로 특정 스테이트에 대해선 업데이트 하지 않도록 할 수 있다.

 

BlocBuilder<BlocA, BlocAState>(
  buildWhen: (previousState, state) {
    // return true/false to determine whether or not
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)

 

BlocSelector

 

BlocBuilder랑 여러모로 유사한데, 개발자가 관찰하고 싶은 상태에 대해서만 새롭게 빌드하도록 한다. 선택된 값이 변화하지 않는다면 불필요한 빌드를 막을 수 있다.

 

BlocSelector<BlocA, BlocAState, SelectedState>(
  selector: (state) {
    // return selected state based on the provided state.
  },
  builder: (context, state) {
    // return widget here based on the selected state.
  },
)

 

BlocProvider 

 

자식 뷰에게 Bloc을 제공할 수 있는 위젯이다.  하나의 동일한 인스턴스 bloc이 여러개의 위젯에 전달될 수 있게 Dependency Inversion 방식으로 제공된다. 안드로이드에서 Hilt를 이용해 컴포넌트를 인젝트 했던 것을 생각하면 된다. 

 

BlocProvider(
  create: (BuildContext context) => BlocA(),
  child: ChildA(),
);

 

MultiBlocProvider 

 

자식에게 여러개의 Bloc을 제공할 수 있다.

 

MultiBlocProvider(
  providers: [
    BlocProvider<BlocA>(
      create: (BuildContext context) => BlocA(),
    ),
    BlocProvider<BlocB>(
      create: (BuildContext context) => BlocB(),
    ),
    BlocProvider<BlocC>(
      create: (BuildContext context) => BlocC(),
    ),
  ],
  child: ChildA(),
)

 

BlocListener 

 

Bloc의 상태 변화에 따라서 listener를 호출하는 작업이다. void 함수로 Widget을 리턴하지 않고 처리해야하는 작업을 넣을 때 사용한다. 예로 로그아웃하거나 로그인 할 때 다른페이지로 이동하는 경우에 사용한다.

 

BlocListener<BlocA, BlocAState>(
  bloc: blocA,
  listener: (context, state) {
    // do stuff here based on BlocA's state
  },
  child: Container()
)

 

BlocConsumer

 

BlocBuilder와 BlocListener를 짬뽕한 형태다. bloc에 대해서 UI를 새로 만들고 상태 변화에 따라서 다른 반응을 해야하는 경우에 쓴다. 두개의 작업을 동시에 할 수 있는 위젯이라 사용하기 편리할 것 같다. 

 

BlocConsumer<BlocA, BlocAState>(
  listenWhen: (previous, current) {
    // return true/false to determine whether or not
    // to invoke listener with state
  },
  listener: (context, state) {
    // do stuff here based on BlocA's state
  },
  buildWhen: (previous, current) {
    // return true/false to determine whether or not
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)

 

RepositoryProvider 

 

자식들에게 저장소를 제공할 수 있는 Flutter Widget이다. BlocProvider와 마찬가지로 DI의 형태로 동일한 Repository를 제공할 수 있다. 

 

RepositoryProvider(
  create: (context) => RepositoryA(),
  child: ChildA(),
);

// with extensions
context.read<RepositoryA>();

// without extensions
RepositoryProvider.of<RepositoryA>(context)

 

 

 

 

 

Bloc State Management Library

Official documentation for the bloc state management library. Support for Dart, Flutter, and AngularDart. Includes examples and tutorials.

bloclibrary.dev