Skip to content

Commit b6d5db8

Browse files
committed
docs(mobile-client): add explanation of BLoC pattern for state management
- Created new documentation page explaining the BLoC pattern used in the mobile client - Covered core components of BLoC: Events, States, and BLoC itself - Provided practical example using AccountBloc - Explained UI integration and data flow in the application
1 parent e15d8eb commit b6d5db8

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: State Management (BLoC)
3+
description: An explanation of the BLoC pattern for state management in the mobile client.
4+
---
5+
import { Aside } from '@astrojs/starlight/components';
6+
7+
The mobile client uses the **BLoC (Business Logic Component)** pattern for state management. This pattern helps to separate the presentation layer from the business logic, making the application more structured, testable, and maintainable.
8+
9+
Every feature in the application that requires managing state has its own BLoC.
10+
11+
### The Core Components of BLoC
12+
13+
A BLoC is made up of three main parts:
14+
15+
1. **Events**: Events are the inputs to a BLoC. They are dispatched from the UI in response to user interactions (e.g., a button press) or lifecycle events (e.g., the page loading). Events are defined as simple classes that extend a base `Event` class.
16+
17+
2. **States**: States are the outputs of a BLoC. They represent a part of the application's state and are emitted by the BLoC in response to events. The UI listens to the stream of states and rebuilds itself to reflect the latest state. States are typically modeled as immutable classes.
18+
19+
3. **BLoC**: The BLoC itself is the component that sits between the UI and the data layer. It receives events, processes them (often by interacting with a repository), and emits new states.
20+
21+
### A Practical Example: `AccountBloc`
22+
23+
Let's look at the `AccountBloc`, which manages the state for the user's account screen.
24+
25+
- **Event**: When a user toggles following a topic, the UI dispatches an `AccountFollowTopicToggled` event, which contains the `Topic` object.
26+
27+
```dart title="lib/account/bloc/account_event.dart"
28+
class AccountFollowTopicToggled extends AccountEvent {
29+
const AccountFollowTopicToggled({required this.topic});
30+
final Topic topic;
31+
}
32+
```
33+
34+
- **BLoC Logic**: The `AccountBloc` listens for this event. In its event handler, it updates the user's preferences by calling the `_userContentPreferencesRepository` and then emits a new state.
35+
36+
```dart title="lib/account/bloc/account_bloc.dart"
37+
on<AccountFollowTopicToggled>(_onAccountFollowTopicToggled);
38+
39+
Future<void> _onAccountFollowTopicToggled(
40+
AccountFollowTopicToggled event,
41+
Emitter<AccountState> emit,
42+
) async {
43+
// ... logic to add/remove topic from preferences ...
44+
final updatedPrefs = // ...
45+
46+
// Persist the change
47+
await _userContentPreferencesRepository.update(item: updatedPrefs);
48+
49+
// Emit the new state
50+
emit(state.copyWith(status: AccountStatus.success, preferences: updatedPrefs));
51+
}
52+
```
53+
54+
- **State**: The `AccountState` holds the current user's `UserContentPreferences`. When the BLoC emits a new state with the updated preferences, the UI rebuilds.
55+
56+
```dart title="lib/account/bloc/account_state.dart"
57+
class AccountState extends Equatable {
58+
const AccountState({
59+
this.status = AccountStatus.initial,
60+
this.preferences,
61+
// ...
62+
});
63+
64+
final AccountStatus status;
65+
final UserContentPreferences? preferences;
66+
// ...
67+
}
68+
```
69+
70+
- **UI Integration**: The `FollowedTopicsListPage` uses a `BlocBuilder` to listen to the `AccountBloc`. When the state changes, it rebuilds the list of topics, and the UI reflects whether the topic is followed or not.
71+
72+
```dart title="lib/account/view/manage_followed_items/topics/followed_topics_list_page.dart"
73+
// ...
74+
body: BlocBuilder<AccountBloc, AccountState>(
75+
builder: (context, state) {
76+
// ... build UI based on state.preferences.followedTopics ...
77+
},
78+
),
79+
// ...
80+
```
81+
82+
This unidirectional data flow—from UI event to BLoC to new UI state—is the foundation of state management in the application.

0 commit comments

Comments
 (0)