简体   繁体   English

无法从 static 方法调用 Flutter Stateful Widget 的 setState

[英]Unable to call setState of Flutter Stateful Widget from a static method

I have this following code where I am displaying a listview, and this listview takes data from a list, which can be dynamically updated from the onConnect() method of STOMP .我在显示列表视图的地方有以下代码,并且此列表视图从列表中获取数据,该列表可以从STOMPonConnect()方法动态更新。 So this onConnect method is expected to be static.所以这个onConnect方法预计是static。

Now, when I receive data from WebSocket, this onConnect method is invoked, which inserts the value in the list.现在,当我从 WebSocket 接收数据时,将调用此 onConnect 方法,该方法将值插入列表中。 But the listview doesn't get the update.但是列表视图没有得到更新。 I am unable to call setState() so that the widget is re-rendered with new data as this onConnect() method is static.我无法调用setState()以便使用新数据重新渲染小部件,因为此onConnect()方法是 static。

Any solution for this.对此的任何解决方案。

List<ChatEntity> chats;
String chatRoomId;
String currentUserEmail;

class Chat extends StatefulWidget {

  Chat(String chatRoomIdC, String currentUserEmailC) {
    chatRoomId = chatRoomIdC;
    currentUserEmail = currentUserEmailC;
  }

  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {
  TextEditingController messageEditingController = new TextEditingController();
 
  _ChatState() {
    client.activate();
  }

  StompClient client = StompClient(
    config: StompConfig(
        url: 'ws://localhost:8080/ws',
        onConnect: onConnectCallback,
        onWebSocketError: (dynamic error) => print(error.toString())),
  );

  static onConnectCallback(StompClient client, StompFrame connectFrame) {
    client.subscribe(
        destination: '/topic/messages/$chatRoomId',
        headers: {},
        callback: (frame) {
          response(frame);
        });
  }

  static response(StompFrame frame) {
    String response = frame.body;
    final parsed = json.decode(response).cast<Map<String, dynamic>>();
    chats.insert(
        0,
        parsed
            .map<ChatEntity>((json) => ChatEntity.fromJson(json))
            .toList()[0]);

 // call setState here to re- render the widget
  }

  Widget chatMessages() {
    return ListView.builder(
        reverse: true,
        itemCount: chats == null ? 0 : chats.length,
        itemBuilder: (context, index) {
          return MessageTile(
            message: chats[index].message,
            sendByMe: currentUserEmail == chats[index].sentBy,
          );
        });
  }

  addMessage() {
    if (messageEditingController.text.isNotEmpty) {
      Map<String, dynamic> chatMessageMap = {
        "chatroomId": chatRoomId,
        "sentBy": currentUserEmail,
        "message": messageEditingController.text
      };
      client.send(
          destination: '/app/chat',
          body: jsonEncode(chatMessageMap),
          headers: {});

      setState(() {
        messageEditingController.text = "";
      });
    }
  }

  @override
  void initState() {
    DatabaseMethods.getChats(chatRoomId).then((val) {
      setState(() {
        chats = val;
      });
    });
    super.initState();
  }

// ignore the build method as it just contains a Scaffold.

In order to use or access setState method you need to be inside of instance methods, not static (class) methods.为了使用或访问setState方法,您需要在实例方法中,而不是 static(类)方法。 So response and onConnectCallback methods shouldn't be static in this case.所以在这种情况下responseonConnectCallback方法不应该是 static 。 Because the StompClient refers to those methods, I would create a StompClient client instance when instantiating the widget (ie in constructor):因为StompClient引用了这些方法,所以我会在实例化小部件时创建一个StompClient client实例(即在构造函数中):

class _ChatState extends State<Chat> {
  TextEditingController messageEditingController = new TextEditingController();
  
  StompClient client;
 
  // Create a StompClient instance when creating new state
  _ChatState() {
    client = StompClient(
      config: StompConfig(
        url: 'ws://localhost:8080/ws',
        onConnect: onConnectCallback,
        onWebSocketError: (dynamic error) => print(error.toString())),
    );
    client.activate();
  }
 
  onConnectCallback(StompClient client, StompFrame connectFrame) {
    ...
  }

  response(StompFrame frame) {
    ...
    // HERE YOU SHOULD BE ABLE TO USE setState() METHOD
  }
...

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

相关问题 从另一个有状态小部件调用一个有状态小部件中的方法 - Flutter - call method in one stateful widget from another stateful widget - Flutter 从 Flutter 中的另一个 dart 文件在有状态小部件 class 下使用 SetState 方法调用 void - Call void with SetState method under stateful widget class from another dart file in Flutter Flutter:如何从单独的Widget方法中调用onPressed()中的setState() - Flutter: how to call setState() in onPressed() from separate Widget method Flutter setState() 从有状态子调用时不刷新小部件 - Flutter setState() not refreshing widget when called from stateful child Flutter-setState未更新内部自定义有状态小部件 - Flutter - setState is not Updating inner Custom Stateful widget Flutter - setState 未更新内部状态小部件 - Flutter - setState not updating inner Stateful Widget Flutter,如何从返回的 Widget 调用 Stateful Widget 内部的函数? - Flutter, how to call a function inside Stateful Widget from a returned Widget? 无法使用 Flutter 有状态小部件 - Unable to work with Flutter Stateful widget 如何在类/有状态小部件之外调用 setState? - How to call setState outside class/stateful widget? 如何从另一个Dart文件中调用有状态的widget(具有表单)方法?-Flutter - How to Call stateful widget(have form) method from another dart file?- Flutter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM