ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [개발일지] Flutter Bloc 상태관리 #2 Bloc Widgets
    Study/Development 2023. 4. 6. 16:38

    Flutter Bloc

    <인프런 개발하는 남자 온라인강의 수강일지>


    Flutter Bloc Widgets

    BlocProvider

    • 지연생성 옵션(lazy): false(사용 시점에서 동시에 사용)
    • 하위 계층 위젯들에서 접근 가능
    • Bloc 생성 후 메모리 반환의 경우 자동으로 해준다
    
    return BlocProvider(
          create: (context) => SampleBloc(),
          lazy: true,
          child: SamplePage(),
        );
    

    MultiBlocProvider

    • BlocProvider 다중 등록
    
    return MultiBlocProvider(
          providers: [
            BlocProvider(create: ((context) => SampleBloc())),
            BlocProvider(create: ((context) => SampleSecondsBloc())),
          ],
          child: SamplePage(),
        );
    

    RepositoryProvider

    • Repository + Provider, Repository(저장소)를 제공하는 위젯
    • 지연생성 옵션(lazy) 통해 관리할 수 있다.
    • 저장소 데이터를 가공할 수 있는 데이터베이스 or 외부 api 통신 등 관리할 때
    
    return RepositoryProvider(
          create: (context) => RepositorySample(),
          child: BlocProvider(
            create: (context) => SampleBlocDI(context.read<RepositorySample>()),
            child: SamplePage(),
          ),
        );
    

    MultiRepositoryProvider

    • RepositoryProvider 다중 등록
    
    return MultiRepositoryProvider(
          providers: [
            RepositoryProvider(
              create: (context) => RepositorySample(),
            ),
            RepositoryProvider(
              create: (context) => RepositorySecondSample(),
            )
          ],
          child: BlocProvider(
            create: (context) => SampleBlocDIMulti(
              context.read<RepositorySample>(),
              context.read<RepositorySecondSample>(),
            ),
            child: SamplePage(),
          ),
        );
    

    BlocBuilder

    • BlocProvider로 생성된 bloc을 사용할 때 쓰는 widget
    • bloc 옵션을 사용하지 않고 사용 시 현 context로부터 bloc을 찾아 변화 감지
    • bloc을 지정하는 케이스의 경우 특별한 케이스에서 사용 권장
    • buildWhen 옵션을 통해 필요한 조건일 때만 변화를 줄 수 있다.
    
    child: BlocBuilder<SampleBloc, int>(
              buildWhen: (previous, current) {
                return current > 10;
              },
              builder: (context, state) {
                return Text(
                  'index : $state',
                  style: const TextStyle(fontSize: 70),
                );
              },
            ),
    

    BlocListener

    • 상태변화에 따른 이벤트만 처리가 필요할 때 사용되는 widget
    • *child위젯의 경우 rebuild가 발생되지 않는다.
    • 사용되는 예
      • 특정 상태가 변경 되었을 때 메시지 팝업을 띄워야 하는 상황
      • bloc간 통신이 필요할 때.
    
    child: BlocListener<SampleBloc, int>(
              listenWhen: (previous, current) => current > 5,
              listener: (context, state) {
                _showMessage(context);
              },
              child: Text(
                context.read<SampleBloc>().state.toString(),
                style: const TextStyle(fontSize: 70),
              ),
            ),
    

    MultiBlocListener

    • BlocListener 다중 등록

    BlocConsumer

    • BlocBuilder와 BlocListener를 합쳐 놓은 위젯
    • 이벤트도 처리하면서 동시에 화면도 변경 해줘야 할 때
    • buildWhen과 listenWhen 조건을 통해 적절한 때에만 변경 및 이벤트처리 가능
    
    child: BlocConsumer<SampleBloc, int>(
              listenWhen: (previous, current) => current > 5,
              listener: (context, state) {
                _showMessage(context);
              },
              buildWhen: (previous, current) => current % 2 == 0,
              builder: (context, state) => Text(
                state.toString(),
                style: const TextStyle(fontSize: 70),
              ),
            ),
    

    BlocSelector

    • Bloc의 상태 중 필요한 부분만 선택적으로 필터링하여 변경에 도움을 주는 widget
    
    BlocSelector<BlocSelectorBloc, BlocSelectorState, bool>(
                  selector: (state) => state.changeState,
                  builder: (context, state) {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        ElevatedButton(
                            onPressed: () {
                              context
                                  .read<BlocSelectorBloc>()
                                  .add(ChangeStateEvent());
                            },
                            child: Text('상태변경')),
                        const SizedBox(width: 15),
                        ElevatedButton(
                            onPressed: () {
                              state
                                  ? context
                                      .read<BlocSelectorBloc>()
                                      .add(ValueEvent())
                                  : null;
                            },
                            child: Text('더하기')),
                      ],
                    );
                  },
                ),
    
    반응형

    댓글

© 2023. titann all rights reserved