Flutter Bloc - mapEventToState 只执行一次
Flutter Bloc - mapEventToState executes only once
大家好,
我是 Flutter 新手。我正在尝试使用 Bloc 进行简单的状态管理。我有一个主屏幕,其中 show/hides 一些小部件取决于状态。在一个单独的屏幕上,我有两个按钮,它们将事件添加到更新状态的流中,然后主屏幕上的小部件对状态更新做出反应。它工作正常,但 UI 仅在第一个事件之后重建,在后续事件中,集团产生状态,但 UI 不更新。同样在 main.dart Material 中,应用程序使用 MultBlocProvider 包装。我来自南非,所以我可能无法立即回复 bc of timezones 但任何帮助将不胜感激。以下是代码片段。
auth_state.dart
class AuthState {
bool isLoggedIn = false;
}
auth_event.dart
enum EventType { login, logout }
class AuthEvent {
late EventType eventType;
AuthEvent.login() {
this.eventType = EventType.login;
}
AuthEvent.logout() {
this.eventType = EventType.logout;
}
}
auth_bloc.dart
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthBloc(AuthState initialState) : super(initialState);
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
switch (event.eventType) {
case EventType.login:
AuthState newState = state;
newState.isLoggedIn = true;
yield newState;
break;
case EventType.logout:
AuthState newState = state;
newState.isLoggedIn = false;
yield newState;
break;
default:
throw Exception('Event not found $event');
}
}
}
home_page.dart(片段)-> bloc comsumer
Padding(
padding: const EdgeInsets.only(right: 30),
child: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {},
builder: (context, state) {
return Visibility(
visible: state.isLoggedIn,
child: IconButton(
key: HomePage.navigateToNotifications,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Notifications()),
);
},
icon: Icon(Icons.circle_notifications,
size: 50, color: HexColor('27B88D'))),
);
}))
test_page.dart(片段)-> 火团事件
ElevatedButton(
onPressed: () =>
BlocProvider.of<AuthBloc>(context).add(AuthEvent.login()),
child: Text('Log User in')),
ElevatedButton(
onPressed: () =>
BlocProvider.of<AuthBloc>(context).add(AuthEvent.logout()),
child: Text('Log User out'))
我发现为状态声明单独的状态 类 比同一状态的新实例更容易。
abstract class AuthState {}
class NotLoggedIn extends AuthState {}
class LoggedIn extends AuthState {}
那么你的mapEventToState
看起来像这样
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
switch (event.eventType) {
case EventType.login:
{
yield LoggedIn();
break;
}
case EventType.logout:
{
yield NotLoggedIn();
break;
}
default:
throw Exception('Event not found $event');
}
}
然后你的 BlocConsumer
看起来像这样,它会按照你的预期重建
Padding(
padding: const EdgeInsets.only(right: 30),
child: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {},
builder: (context, state) {
return Visibility(
visible: state is LoggedIn ? true : false,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.circle_notifications,
size: 50, color: Colors.amber)),
);
},
),
)
大家好,
我是 Flutter 新手。我正在尝试使用 Bloc 进行简单的状态管理。我有一个主屏幕,其中 show/hides 一些小部件取决于状态。在一个单独的屏幕上,我有两个按钮,它们将事件添加到更新状态的流中,然后主屏幕上的小部件对状态更新做出反应。它工作正常,但 UI 仅在第一个事件之后重建,在后续事件中,集团产生状态,但 UI 不更新。同样在 main.dart Material 中,应用程序使用 MultBlocProvider 包装。我来自南非,所以我可能无法立即回复 bc of timezones 但任何帮助将不胜感激。以下是代码片段。
auth_state.dart
class AuthState {
bool isLoggedIn = false;
}
auth_event.dart
enum EventType { login, logout }
class AuthEvent {
late EventType eventType;
AuthEvent.login() {
this.eventType = EventType.login;
}
AuthEvent.logout() {
this.eventType = EventType.logout;
}
}
auth_bloc.dart
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthBloc(AuthState initialState) : super(initialState);
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
switch (event.eventType) {
case EventType.login:
AuthState newState = state;
newState.isLoggedIn = true;
yield newState;
break;
case EventType.logout:
AuthState newState = state;
newState.isLoggedIn = false;
yield newState;
break;
default:
throw Exception('Event not found $event');
}
}
}
home_page.dart(片段)-> bloc comsumer
Padding(
padding: const EdgeInsets.only(right: 30),
child: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {},
builder: (context, state) {
return Visibility(
visible: state.isLoggedIn,
child: IconButton(
key: HomePage.navigateToNotifications,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Notifications()),
);
},
icon: Icon(Icons.circle_notifications,
size: 50, color: HexColor('27B88D'))),
);
}))
test_page.dart(片段)-> 火团事件
ElevatedButton(
onPressed: () =>
BlocProvider.of<AuthBloc>(context).add(AuthEvent.login()),
child: Text('Log User in')),
ElevatedButton(
onPressed: () =>
BlocProvider.of<AuthBloc>(context).add(AuthEvent.logout()),
child: Text('Log User out'))
我发现为状态声明单独的状态 类 比同一状态的新实例更容易。
abstract class AuthState {}
class NotLoggedIn extends AuthState {}
class LoggedIn extends AuthState {}
那么你的mapEventToState
看起来像这样
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
switch (event.eventType) {
case EventType.login:
{
yield LoggedIn();
break;
}
case EventType.logout:
{
yield NotLoggedIn();
break;
}
default:
throw Exception('Event not found $event');
}
}
然后你的 BlocConsumer
看起来像这样,它会按照你的预期重建
Padding(
padding: const EdgeInsets.only(right: 30),
child: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {},
builder: (context, state) {
return Visibility(
visible: state is LoggedIn ? true : false,
child: IconButton(
onPressed: () {},
icon: Icon(Icons.circle_notifications,
size: 50, color: Colors.amber)),
);
},
),
)