не могу обновить просмотр списка с данными socket.io во флаттере? - PullRequest
1 голос
/ 06 апреля 2020

Я разрабатываю бэкэнд, используя node.js и express и MongoDB и socket.io, а во внешнем интерфейсе я использую flutter и dart.

Я использование emit для отправки данных из бэкэнда в приложение flutter, и оно работает нормально, и я могу получить сообщение, чтобы проблема не была в бэкэнде.

при получении этого сообщения я хочу добавить это к списку и затем устанавливает, чтобы обновить sh метод сборки, чтобы перестроить метод сборки, но это терпит неудачу и дает мне эту ошибку:

[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--');
    });

Я использую это в методе сборки, и я объявил список postData в верхней части класса состояния.

Я также использую будущую функцию внутри состояния init метод, чтобы получить данные из бэкэнда, а затем установить состояние, чтобы сделать 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]),
  );

Обновление

после тестирования я обнаружил, что проблема не возникает в первый раз, когда пользователь переходит на этот экран, но в другое время она не срабатывает.

а как это решить?

1 Ответ

0 голосов
/ 08 мая 2020

После слишком долгих поисков я обнаружил, что проблема возникает из-за флаттера, поскольку я использовал нижнюю панель навигации с четырьмя экранами, и они возвращают информацию о состоянии каждый раз, когда я go обращаюсь к ним через некоторое время.

наконец, я смог решить эту проблему с помощью виджета индексированного стека.

Спасибо,

...