bloc extension_methods

Sunny·2022년 6월 7일

bloc

다트 27에서 확장된 방법이 하나 추가되었다.

flutter_bloc이 provider 패키지에 종속되어 상속된 위젯의 사용이 단순화됌

blocProvider, MultiBlocProvider, RepositoryProvider, MultiRepositoryProvider widgets, flutter_bloc exports the ReadContext, WatchContext, selectContext 확장자를 export함

context.read()

가장 가까운 상위 인스턴스를 검색하며, 기능적으로는 BlocProvider.of(context)와 동일, context.read는 onPressed callback에서 event add 하기 위해 bloc instance 검색하는데 사용!

context.read()는 T를 Listener하지 못함 .. 제공된 개체 유형 T가 변경되면 context.read는 위젯 재구성을 trigger하지 않음


// Do
onPressed() {
  context.read<CounterBloc>().add(CounterIncrementPressed()),
}

// Avoid - build method 안에서는 context.read 사용을 피해라

Widget build(BuildContext context) {
  final state = context.read<MyBloc>().state;
  return Text('$state');
}

// bloc state change => text widget 다시 작성 x => 오류 발생하기 쉬움 => blocBuilder 또는 context.watch를 사용함 / 상태 변화에 대응하여 다시 빌드하기 위해!! 

context.watch()

T 유형의 가장 가까운 상위 인스턴스를 제공하지만 인스턴스의 변경 내용도 Listening 함 / 기능적으로 blocProvider.of(context, listen:true)와 동일함

제공된 유형 T의 개체가 변경되는 경우 context.watch가 트리거를 재빌드함
context.watch는 단지 엑세스 할 수 있는데, statelesswidget이나 상태클래스의 빌드 메소드 안에서만!!.

// Do - use BlocBuilder instead of context.watch to explicitly scope rebuilds.
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      body: BlocBuilder<MyBloc, MyState>(
        builder: (context, state) {
          // Whenever the state changes, only the Text is rebuilt.
          return Text(state.value);
        },
      ),
    ),
  );
}
// alternatively 

Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      body: Builder(
        builder: (context) {
          // Whenever the state changes, only the Text is rebuilt.
          final state = context.watch<MyBloc>().state;
          return Text(state.value);
        },
      ),
    ),
  );
}
// Do - use Builder and context.watch as MultiBlocBuilder.
Builder(
  builder: (context) {
    final stateA = context.watch<BlocA>().state;
    final stateB = context.watch<BlocB>().state;
    final stateC = context.watch<BlocC>().state;

    // return a Widget which depends on the state of BlocA, BlocB, and BlocC
  }
);

//Avoid - 빌드 메소드의 상위 위젯이 상태에 따라 달라지지않는 지 확인


Widget build(BuildContext context) {
  // Whenever the state changes, the MaterialApp is rebuilt
  // even though it is only used in the Text widget.
  final state = context.watch<MyBloc>().state;
  return MaterialApp(
    home: Scaffold(
      body: Text(state.value),
    ),
  );
}


context.select

context.watch<T.(), context.select<T,R>(R function(T Value)) provide => t 유형의 가장 가까운 상위 인스턴스를 제공하고, 변경 내용을 listening 함!! context.watch와 다르게, context.select를 사용하면 상태의 더 작은 부분에서 변경 사항을 listening 할 수 있음

Widget build(BuildContext context) {
final name = context.select((ProfileBloc bloc) => bloc.state.name);
return Text(name);
}
// profileBloc의 속성 이름이 변경될 때만 위젯을 재구성함

//Do - context 대신 Bloc Selector를 사용하기 => 재 빌드 범위를 명시적으로 지정하려면 선택
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: BlocSelector<ProfileBloc, ProfileState, String>(
selector: (state) => state.name,
builder: (context, name) {
// Whenever the state.name changes, only the Text is rebuilt.
return Text(name);
},
),
),
);
}

//alternatively
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Builder(
builder: (context) {
// Whenever state.name changes, only the Text is rebuilt.
final name = context.select((ProfileBloc bloc) => bloc.state.name);
return Text(name);
},
),
),
);
}

//Avoid - context.select를 사용할 때 빌드 메소드의 상위 위젯은 상태에 따라 달라지지 않음
@override
Widget build(BuildContext context) {
// Whenever the state.value changes, the MaterialApp is rebuilt
// even though it is only used in the Text widget.
final name = context.select((ProfileBloc bloc) => bloc.state.name);
return MaterialApp(
home: Scaffold(
body: Text(name),
),
);
}

// context.select를 사용하여, 선택 항목이 변경될 떄 전체 위젯이 다시 재빌드 돼요.

profile
즐거움을 만드는 사람

0개의 댓글