产生新状态后,Flutter 状态不会更新
Flutter state not update after yield new state
我在 flutter 应用程序中使用 bloc,我的问题是当产生新状态时视图没有更新。
我想将新消息添加到我的消息列表中。并且我使用新数据产生相同的状态,但是在将新消息添加到列表后我的视图没有更新。
集团:
class ChatBloc extends Bloc<ChatEvent, ChatState> {
@override
ChatState get initialState => ChatInitial();
@override
Stream<ChatState> mapEventToState(ChatEvent event) async* {
if (event is AddToMessages) {
yield* _mapAddToMessagesEventToState(event.chatMessage);
}
}
Stream<ChatState> _mapAddToMessagesEventToState(ChatMessage chatMessage) async* {
List<ChatMessage> chatMessages = (state as DataLoaded).chatMessages;
chatMessages.insert(0, chatMessage);
yield DataLoaded(chatMessages: chatMessages);
}
}
事件:
abstract class ChatEvent extends Equatable {}
class AddToMessages extends ChatEvent {
final ChatMessage chatMessage;
AddToMessages({@required this.chatMessage});
@override
List<Object> get props => [chatMessage];
}
状态:
abstract class ChatState extends Equatable {
const ChatState();
}
class ChatInitial extends ChatState {
const ChatInitial();
@override
List<Object> get props => [];
}
class DataLoaded extends ChatState {
final List<ChatMessage> chatMessages;
const DataLoaded({this.chatMessages});
@override
List<Object> get props => [chatMessages];
}
和视图:
class ChatScreen extends StatelessWidget {
Widget createBody(ChatState state, BuildContext context) {
if (state is DataLoaded) {
return Column(
children: <Widget>[
MessagesList(
messages: state.chatMessages,
),
SendBar(
onMessage: (message) => BlocProvider.of<ChatBloc>(context).add(
AddToMessages(
chatMessage: ChatMessage(
chatMessageType: ChatMessageType.TEXT,
dateTime: DateTime.now(),
message: message,
userId: store.state.userProfile.id,
),
),
),
),
],
);
} else {
return Container();
}
}
@override
Widget build(BuildContext context) {
return BlocProvider<ChatBloc>(
create: (context) {
return ChatBloc(chatRepository: chatRepository)..add(DataLoaded(chatMessages: []));
},
child: BlocListener<ChatBloc, ChatState>(
listener: (context, state) async {},
child: BlocBuilder<ChatBloc, ChatState>(
builder: (context, state) {
return Scaffold(
body: createBody(state, context),
);
},
),
),
);
}
}
当我添加新消息时,视图没有更新。
我哪里错了。
编辑: 毕竟因为你使用的是 equatable,而且因为当你发出一个新状态时,你只是通过插入一个改变旧状态的列表向其中发送消息,然后使用相同的列表发出旧状态,因此当 bloc 比较两个状态时,并且由于状态 class 扩展了 equatable,因此 bloc 认为它们相同并且不会发出 state
解决方案:删除 equatable
或
使用不可变列表,这样您就可以发出一个新状态,该状态与之前的状态 属性 不同,并且可以通过 bloc
来区分
有些东西的列表不能与 Equatable 一起正常工作。即使 List 元素不同,它也总是 returns true。
所以我有一个解决方法。我添加了另一个列表 属性 和一个布尔值 属性 来帮助在 State of Bloc 中拥有大量房产的人。
class DataLoaded extends ChatState {
final List<Member> roomMembers;
final List<ChatMessage> chatMessages;
final bool isOpen;
final List<Object> allElements;
DataLoaded({this.chatMessages, this.roomMembers, this.isOpen})
: allElements = [...chatMessages, ...roomMembers, isOpen];
@override
List<Object> get props => allElements;
}
希望对你有所帮助,对我很有效:)
我在 flutter 应用程序中使用 bloc,我的问题是当产生新状态时视图没有更新。 我想将新消息添加到我的消息列表中。并且我使用新数据产生相同的状态,但是在将新消息添加到列表后我的视图没有更新。 集团:
class ChatBloc extends Bloc<ChatEvent, ChatState> {
@override
ChatState get initialState => ChatInitial();
@override
Stream<ChatState> mapEventToState(ChatEvent event) async* {
if (event is AddToMessages) {
yield* _mapAddToMessagesEventToState(event.chatMessage);
}
}
Stream<ChatState> _mapAddToMessagesEventToState(ChatMessage chatMessage) async* {
List<ChatMessage> chatMessages = (state as DataLoaded).chatMessages;
chatMessages.insert(0, chatMessage);
yield DataLoaded(chatMessages: chatMessages);
}
}
事件:
abstract class ChatEvent extends Equatable {}
class AddToMessages extends ChatEvent {
final ChatMessage chatMessage;
AddToMessages({@required this.chatMessage});
@override
List<Object> get props => [chatMessage];
}
状态:
abstract class ChatState extends Equatable {
const ChatState();
}
class ChatInitial extends ChatState {
const ChatInitial();
@override
List<Object> get props => [];
}
class DataLoaded extends ChatState {
final List<ChatMessage> chatMessages;
const DataLoaded({this.chatMessages});
@override
List<Object> get props => [chatMessages];
}
和视图:
class ChatScreen extends StatelessWidget {
Widget createBody(ChatState state, BuildContext context) {
if (state is DataLoaded) {
return Column(
children: <Widget>[
MessagesList(
messages: state.chatMessages,
),
SendBar(
onMessage: (message) => BlocProvider.of<ChatBloc>(context).add(
AddToMessages(
chatMessage: ChatMessage(
chatMessageType: ChatMessageType.TEXT,
dateTime: DateTime.now(),
message: message,
userId: store.state.userProfile.id,
),
),
),
),
],
);
} else {
return Container();
}
}
@override
Widget build(BuildContext context) {
return BlocProvider<ChatBloc>(
create: (context) {
return ChatBloc(chatRepository: chatRepository)..add(DataLoaded(chatMessages: []));
},
child: BlocListener<ChatBloc, ChatState>(
listener: (context, state) async {},
child: BlocBuilder<ChatBloc, ChatState>(
builder: (context, state) {
return Scaffold(
body: createBody(state, context),
);
},
),
),
);
}
}
当我添加新消息时,视图没有更新。 我哪里错了。
编辑: 毕竟因为你使用的是 equatable,而且因为当你发出一个新状态时,你只是通过插入一个改变旧状态的列表向其中发送消息,然后使用相同的列表发出旧状态,因此当 bloc 比较两个状态时,并且由于状态 class 扩展了 equatable,因此 bloc 认为它们相同并且不会发出 state
解决方案:删除 equatable
或
使用不可变列表,这样您就可以发出一个新状态,该状态与之前的状态 属性 不同,并且可以通过 bloc
来区分有些东西的列表不能与 Equatable 一起正常工作。即使 List 元素不同,它也总是 returns true。
所以我有一个解决方法。我添加了另一个列表 属性 和一个布尔值 属性 来帮助在 State of Bloc 中拥有大量房产的人。
class DataLoaded extends ChatState {
final List<Member> roomMembers;
final List<ChatMessage> chatMessages;
final bool isOpen;
final List<Object> allElements;
DataLoaded({this.chatMessages, this.roomMembers, this.isOpen})
: allElements = [...chatMessages, ...roomMembers, isOpen];
@override
List<Object> get props => allElements;
}
希望对你有所帮助,对我很有效:)