본문 바로가기

✏️/Flutter

[flutter] 새로운 Bloc Widget 두둥 등장! - BlocSelector

728x90

이번에 bloc 버전이 7.1.x 대로 올라오면서, BlocSelector가 생겼습니다! 🥳🥳

이전 포스팅에서, 잠깐 BlocSelector에 대해서 언급한 적이 있는데요,
오늘은 간단하게 소개만 했던 BlocSelector를 사용해보고, 알아가는 느낌(?)으로 글을 작성해보겠습니다.


BlocSelector

 

pub.dev flutter_bloc에서는 다음과 같이 소개하고 있습니다.

BlocSelector는 BlocBuilder와 유사합니다.
하지만, 개발자가 state를 기준으로 값을 선택하여 업데이트를 필터링 할 수 있는 Flutter 위젯입니다.
선택한 값이 변경되지 않으면, 불필요한 빌드가 방지 됩니다. 
BlocSelector가 builder를 호출 해야하는지 여부를 정확하게 결정하려면 선택한 값이 변경 불가능(immutable) 해야 합니다.

BlocSelector is a Flutter widget which is analogous to BlocBuilder but allows developers to filter updates by selecting a new value based on the current bloc state. but allows developers to filter updates by selecting a new value based on the current bloc state. Unnecessary builds are prevented if the selected value does not change. 
The selected value must be immutable in order for BlocSelector to accurately determine whether builder should be called again.

 

워.. 친절하게 설명 되어 있듯이, 기존 BlocBuilder 사용 시 무분별하게 state 변화에 따라 빌드 되던 것을, 선택한 state를 기준으로 변경을 감지하여 rebuild를 한다고 합니다!

 

엇,, 그렇다면 기존 BlocBuilder Widget의 buildWhen과 어떠한 차이점이 있을까요?

buildWhen으로도 충분히 bloc state를 기준으로 builder를 호출이 가능하지 않나..?...
굳이 BlocSelector를 사용해야 하는 이유가 뭘까...?

~~~ 점점 생각에 생각을 빠지는 중 ~~~

궁금해서 flutter_bloc 레포에 검색해본 결과 저처럼 생각한 분이 이미 있더라고요 ㅋㅋㅋ 그래서 덕분에 다음과 같은 차이점이 있음을 알 수 있었습니다.

buildWhen is an optimization and does not guarantee that builder will not be called. If you want to strictly select a part of a bloc state to be available to the builder you can use the BlocSelector widget introduced in flutter_bloc v7.1.0. Hope that helps!


음.. 빌더가 사용 할 수 있는 보장된 BlocState를 사용하고 싶은 경우, BlocSelector를 사용하라고 합니다. null-safety 부분이 추가되면서 State가 null에 대한 안정성을 보장받기 위해 생겨났지 않았나,,, 조심스럽게 생각해봅니다. 아직 확실히 와닿지는 않지만, 뭐 나온지 얼마 안 됐고 하니, 이런 컨셉을 유지하면서 계속 update 될 듯 싶습니다.ㅎㅎ

 

 

그럼 다시 돌아와, BlocSelector를 한번 사용해봅시다!

 

 

BlocSelector의 원형은 다음과 같습니다.

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.
  },
)

 

위 원형을 참고해서 간단하게, 메거진의 좋아요 버튼을 만들어보겠습니다.

floatingActionButton:
	BlocSelector<MagazineCubit, MagazineState, bool>(
    	selector: (state) => state.magazine.isLike,
        builder: ((context, isLike) {
        	return FloatingActionButton( 
            	elevation: 0,
                onPressed: () {
                	_magazineCubit.updateLike(state.magazine.id);
                },
                child: isLike
                    ? Icon(Icons.favorite_border)
                    : Icon(Icons.favorite),
              );
       }
 )),

 

메거진에 isLike라는 프로퍼티가 있고, button을 누를 때마다 메거진의 like을 올려주는 cubit이 실행됩니다.

이때, selected한 state인 isLike을 기준으로 변경 되었을 경우 rebuild하게 되는데요.

state에 따라 아이콘이 변하는 것을 확인 하실 수 있습니다.

 

 

 

 

간단하게, state 변경에 따라 rebuild가 필요한 부분을 찾고 이 부분을 selected 하면 된다~ 정도의 컨셉인 듯 합니다!

 

아직 공식문서에 example이 없어서, 제가 이해한 컨셉(?)이 맞나 궁금하네요 ㅎㅎ...