flutter_bloc 라이브러리 위에 구축된 일반적으로 사용되는 BLoC 패턴의 모음으로, Flutter 애플리케이션에서 상태 관리를 간소화하도록 설계되었습니다. 로딩 상태, 오류 처리, 폼 관리와 같은 일반적인 사용 사례를 위한 즉시 사용 가능한 구현을 제공하여 반복 코드를 줄이고 코드 일관성을 향상시킵니다. 이 패키지는 BLoC를 활용한 반응형 프로그래밍의 최선의 실천 방법을 따르며 재사용 가능하고 잘 구조화된 패턴을 제공함으로써 개발자의 생산성을 높입니다.
사용 사례
로딩 상태 관리
API 오류 처리
폼 상태 관리
사용자 인증 흐름
재시도 로직을 가진 데이터 가져오기
화면 전환 간 상태 유지
주요 기능
사전 구축된 BLoC 패턴
보일러플레이트 감소
일관된 오류 처리
flutter_bloc과의 간편한 통합
비동기 작업 지원
관심사의 명확한 분리
적합한 대상
flutter_bloc을 사용하는 Flutter 개발자
일관된 상태 관리가 필요한 프로젝트
BLoC 사용을 표준화하려는 팀
복잡한 UI 상태 로직을 가진 애플리케이션
고려 사항
flutter_bloc 설치가 필요합니다
패키지 크기가 약간 증가할 수 있습니다
중소에서 대규모 앱에 가장 적합
간단한 상태 요구 사항에 적합하지 않음
고급 시나리오를 위한 제한된 사용자 정의
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Flutter BLoC patterns
A set of most common BLoC use cases build on top flutter_bloc library.
Key contepts
BLoC
BLoC, aka Business Logic Component, is a state management system for Flutter. It's main goal is to separate business logic from the presentation layer. The BLoC handles user actions or any other events and generates new state for the view to render.
Repository
A Repository to handles data operations. It knows where to get the data from and what API calls to make when data is updated. A Repository can utilize a single data source as well as it can be a mediator between different data sources, such as database, web services and caches.
ViewStateBuilder
ViewStateBuilder is responsible for building the UI based on the view state. It's a wrapper over the BlocBuilder widget so it accepts a bloc object and a set of handy callbacks, which corresponds to each possible state:
initial - informs the presentation layer that view is in it's initial state, and no action has taken place yet,
loading - informs the presentation layer that the data is being loaded, so it can display a loading indicator,
refreshing - informs the presentation layer that the data is being refreshed, so it can display a refresh indicator or/and the current state of list items,
data - informs the presentation layer that the loading is completed and a nonnull and not empty data was retrieved,
empty - informs the presentation layer that the loading is completed, but null or empty data was retrieved,
error - informs the presentation layer that the loading or refreshing has ended with an error. It also provides an error that has occurred.
ViewStateListener
ViewStateListener is responsible for performing an action based on the view state. It should be used for functionality that needs to occur only in response to a state change such as navigation, showing a SnackBar etc. ViewStateListener is a wrapper over the BlocListener widget so it accepts a bloc object as well as a child widget and a set of handy callbacks corresponding to a given state:
onLoading - informs the presentation layer that the data is being loaded,
onRefreshing - informs the presentation layer that the data is being refreshed,
onData - informs the presentation layer that the loading is completed and a nonnull and not empty data was retrieved,
onEmpty - informs the presentation layer that the loading is completed, but null or empty data was retrieved,
onError - informs the presentation layer that the loading or refreshing has ended with an error. It also provides an error that has occurred.
Features
ListBloc
The most basic use case. Allows to fetch, refresh and display a list of items without filtering and pagination. Thus, ListBloc should be used only with a reasonable amount of data.
ListBloc provides the methods for loading and refreshing data:
loaditems() - most suitable for initial data fetch or for retry action when the first fetch fails,
refreshitems() - designed for being called after the initial fetch succeeds.
To display the current view state ListBloc cooperates with BlocBuilder as well as ViewStateBuilder.
ListRepository
A ListRepository implementation should provide only one method:
Future<List<T>> getAll(); - this method is responsible for providing all the data to the ListBloc.
A list BLoC with pagination but without filtering. It works best with Infinite Widgets but a custom presentation layer can be provided as well.
Page
Contains information about the current page, this is number and size.
PagedList
List of items with information if there are more items or not.
PagedListRepository
PagedListRepository comes with only one method:
Future<List<T>> getAll(Page page); - this method retrieves items meeting the pagination restriction provided by the page object.
When items are exceeded it should return an empty list or throw PageNotFoundException. PagedListBloc will handle both cases in the same way.
A list BLoC with pagination and filtering. It works best with Infinite Widgets but a custom presentation layer can be provided as well.
Page
Contains information about the current page, this is number and size.
PagedList
List of items with information if there are more items or not.
PagedListFilterRepository
PagedListFilterRepository provides only two methods:
Future<List<T>> getAll(Page page); - retrieves items meeting the pagination restriction provided by the page object.
Future<List<T>> getBy(Page page, F filter); - retrieves items meeting pagination as well as the filter restrictions provided by the page and filter objects.
When items are exceeded it should return an empty list or throw PageNotFoundException. PagedListFilterBloc will handle both cases in the same way.
Where:
T is the item type returned by this repository,
F is the filter type, which can be primitive as well as complex object.
A BLoC that allows to fetch a single item with given identifier.
DetailsRepository
DetailsRepository comes with only one method:
Future<T> getById(I id); - this method retrieves an item with given id. When there's no item matching the id the null should be returned. In this cases the DetailsBloc will emit Empty state.
Where:
T is the item type returned by this repository,
I is the id type, it can be primitive as well as a complex object.
A BLoC that exposes the Internet connection state to the UI.
Connection
The Internet connection state. It can be either online or offline.
ConnectionRepository
ConnectionRepository notifies about connection state changes, such as going online or offline.
Please notice, that this is only a contract and a developer needs to provide an implementation. This can be done using one of many popular packages, like:
Or whatever works for you. A sample implementation using connectivity_plus may look as follows:
classConnectivityPlusRepositoryimplementsConnectionRepository{
@overrideStream<Connection> observe() {
// Required due to https://github.com/fluttercommunity/plus_plugins/issues/2527returnMergeStream([
Stream.fromFuture(_connectivity.checkConnectivity()),
_connectivity.onConnectivityChanged,
]).map(
(ConnectivityResult result) => result != ConnectivityResult.none
? Connection.online
: Connection.offline,
);
}
}
ConnectionBuilder
ConnectionBuilder is responsible for building the UI based Connection state.
It's a wrapper over the BlocBuilder widget so it accepts a bloc object and provides WidgetBuilder functions for possible states:
online - a builder for the the Connection.online state,
offline - a builder for the the Connection.offline state,
ConnectionListener
ConnectionListener is responsible for performing a one-time action based on the Connection state change.
It should be used for functionality that needs to occur only once in response to the Connection state change such as navigation, SnackBar, showing a Dialog, etc.
ConnectionListener is a wrapper over the BlocListener widget so it accepts a bloc object as well as a child widget. It also takes ConnectionCallback functions for possible states:
onOnline - a callback for the the Connection.online state,
onOffline - a callback for the Connection.offline state.