在flutter中不能用socket.io数据更新listview?

问题描述 投票:1回答:1

我正在开发一个后台,使用 node.jsexpressMongoDBsocket.io 而在前端,我使用的是 flutterdart.

我正在使用 emit 将数据从后台发送至 flutter 应用,并且工作正常,我可以收到消息,所以问题不在后台。

当我收到该消息时,我想把它添加到一个列表中,然后设置状态刷新构建方法,以重建构建方法,但它失败了,并给我那个错误。

[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: setState() called after dispose(): _NewsState#a696c(lifecycle state: defunct, not mounted)
E/flutter (11883): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter (11883): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (11883): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().

这是我的代码片段,用来监听来自后台的事件。

Provider.of<IoProvider>(context).globalSocket.connect();
    Provider.of<IoProvider>(context).globalSocket.on('posts', (data) {
      if (data['action'] == 'add') {
        setState(() {
          postData.add(data['data']);
        });
      }
      print('--emit--');
    });

我在构建方法中使用了这个,并且我在state类的顶部声明了postData列表。

我还在init state方法中使用了一个未来函数来获取来自后端的数据,然后setstate使postData等于来自后端的响应数据,并且其成功。

代码片段。

Future getPosts() async {
    var data = await PostController().fetchPosts();

    if (data['success'] == true) {
      setState(() {
        postData = data['posts'];
      });
    }
  }

在initState里面

@override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      getPosts(context);
    });
      _editingController = TextEditingController();
  }

在构建方法里面:

ListView.builder(
    itemCount: postData.length,
    itemBuilder: (context , index) => PostView(postData[index]),
  );

更新

经过测试,我发现这个问题没有发生在用户第一次导航到该屏幕,但在其他时间它失败。

但如何解决呢?

list flutter dart socket.io setstate
1个回答
0
投票

经过太多搜索,我发现这个问题是由flutter本身发生的,因为我使用的是底部的导航栏,有四个屏幕,而且每次我进入它们的时候,它们都会在一段时间后调用initstate。

最后,我通过使用索引堆栈小部件解决了这个问题。

谢谢你。

© www.soinside.com 2019 - 2024. All rights reserved.