无法在 flutter 中使用 socket.io 数据更新列表视图?
cant update listview with socket.io data in flutter?
我正在使用 node.js
和 express
以及 MongoDB
和 socket.io
开发后端,在前端,我使用 flutter
和dart
.
我正在使用 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--');
});
我在构建方法中使用了它,并且我在状态 class.
的顶部声明了 postData 列表
我还在 init state 方法中使用 future 函数从后端获取数据,然后 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]),
);
更新
经过测试,我发现问题不会在用户第一次导航到该屏幕时发生,但在其他时候就会失败。
但是怎么解决呢?
经过大量搜索,我发现问题是由 flutter 本身引起的,因为我使用的是带有四个屏幕的底部导航栏,并且在一段时间后每次访问它们时它们都会调用 initstate。
最后,我使用索引堆栈小部件解决了这个问题。
谢谢,
我正在使用 node.js
和 express
以及 MongoDB
和 socket.io
开发后端,在前端,我使用 flutter
和dart
.
我正在使用 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--');
});
我在构建方法中使用了它,并且我在状态 class.
的顶部声明了 postData 列表我还在 init state 方法中使用 future 函数从后端获取数据,然后 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]),
);
更新
经过测试,我发现问题不会在用户第一次导航到该屏幕时发生,但在其他时候就会失败。
但是怎么解决呢?
经过大量搜索,我发现问题是由 flutter 本身引起的,因为我使用的是带有四个屏幕的底部导航栏,并且在一段时间后每次访问它们时它们都会调用 initstate。
最后,我使用索引堆栈小部件解决了这个问题。
谢谢,