【问题标题】:Flutter state not update after yield new state产生新状态后颤振状态不更新
【发布时间】:2020-08-04 18:56:00
【问题描述】:

我在颤振应用程序中使用 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),
            );
          },
        ),
      ),
    );
  }
}

当我添加新消息时,视图不会更新。 我的错在哪里。

【问题讨论】:

    标签: flutter bloc


    【解决方案1】:

    编辑: 毕竟是因为您使用的是 equatable,并且因为当您发出一个新状态时,您只是通过向其中插入一条消息来更改旧状态的列表,然后发出具有相同列表的旧状态,因此当 bloc 比较两个状态时,并且由于 state 类扩展为 equatable,bloc 认为它们相同并且不发出状态

    解决方案:删除等价的

    使用不可变列表,这样您就可以发出一个新状态,该状态具有与前一个不同的属性并且可以通过 bloc 进行区分

    【讨论】:

    • 那么,我必须在状态类中删除const 吗?
    • 如果你从其他地方调用它,你可以保留它(这是我怀疑的),但无论如何从 mapEventToState() 你不应该调用它,特别是使用 equatable,所以添加一个非-const 构造函数必须解决您的问题,请参阅答案中的链接
    • 我不想让出其他状态。
    • 您是否尝试删除 const 构造函数,但没有成功?抱歉,因为我没有你的代码,所以我无法为你试一试
    • 我这样定义DataLoaded({this.chatMessages});
    【解决方案2】:

    Equatable 无法正常工作的列表。即使 List 元素不同,它也总是返回 true。

    所以我有一个解决方法。我添加了另一个 List 属性和一个 bool 属性来帮助在 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;
    }
    

    希望对你有帮助,对我有用:)

    【讨论】:

      猜你喜欢
      • 2021-05-23
      • 2021-11-19
      • 2022-01-18
      • 1970-01-01
      • 2021-06-01
      • 2021-10-21
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      相关资源
      最近更新 更多