简体   繁体   English

Flutter state 良品后未更新 state

[英]Flutter state not update after yield new state

I am using bloc in flutter app and my problem is view is not update when yield new state.我在 flutter 应用程序中使用 bloc,我的问题是当产生新的 state 时视图没有更新。 I want to add new message to my list of messages.我想将新消息添加到我的消息列表中。 and I yield same state with new data but my view doesn't update after adding new message to list.我用新数据生成了相同的 state,但是在将新消息添加到列表后我的视图没有更新。 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);
  }
}

event:事件:

abstract class ChatEvent extends Equatable {}
class AddToMessages extends ChatEvent {
  final ChatMessage chatMessage;
  AddToMessages({@required this.chatMessage});
  @override
  List<Object> get props => [chatMessage];
}

state: state:

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];
}

and View:和查看:

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

When I add new message, view doesn't update.当我添加新消息时,视图不会更新。 Where is my mistake.我的错在哪里。

Edit: turns out after all that because you are using equatable, and because when you emit a new state, you are only changing the list of the old state by inserting a message into it, then emitting the old state with the same list,so when bloc compares the two states, and because the state class extends equatable, the bloc considers them the same and doesn't emit a state编辑:毕竟因为您使用的是 equatable,并且因为当您发出新的 state 时,您只是通过在其中插入一条消息来更改旧 state 的列表,然后发出旧的 Z9ED39E2EA931586B73EZEF8当 bloc 比较这两个状态时,因为 state class 扩展为 equatable,所以 bloc 认为它们相同并且不会发出 state

solution: remove the equatable解决方案:删除等价

or或者

use immutable lists so you can emit a new state that has a different property than the previous one and can be distinguished by bloc使用不可变列表,这样您就可以发出一个新的 state,它具有与前一个不同的属性并且可以通过 bloc 来区分

List of something is not working properly with Equatable. Equatable 无法正常工作的列表。 It always returns true even if List elements are not same.即使 List 元素不相同,它也总是返回 true。

So I have a workaround for this.所以我有一个解决方法。 I added another List property and a bool property to help people who has lots of properties in State of Bloc.我添加了另一个 List 属性和一个 bool 属性来帮助在 Bloc 的 State 中拥有大量属性的人。

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;
}

I hope it will help you, it works on me:)我希望它会帮助你,它适用于我:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM