如何从回调函数调用changeNotifier?扑

发布于 2025-01-24 16:47:06 字数 1164 浏览 4 评论 0原文

我在Flutter应用程序中调用构建功能的函数。 当我调用notifyListeners();从异步回调函数我获得以下例外:

setState() or markNeedsBuild() called during build.

我的提供商:我的

class TechTaskProvider extends ChangeNotifier {
  ...
  void requestTasks() {
   
    CollectionReference<Map<String, dynamic>> _collection =
        FirebaseFirestore.instance
            .collection('techTasks')
            .doc(_currentTech!.uid)
            .collection('techTasks');

    _collection.get().then((s) {
        _handleResult(s);
        notifyListeners();
    });
}
  

触发器窗口:我的触发器:

class Trigger extends StatefulWidget {
  const Trigger({Key? key}) : super(key: key);

  @override
  State<Trigger> createState() => _TriggerState();
}

class _TriggerState extends State<Trigger> {
  @override
  Widget build(BuildContext context) {
    MyProvider _myProv = Provider.of<MyProvider>(context);
    //
    if (isFirstRun) {
      //Set the first techincian:
      isFirstRun = false;
      // //Trigger Firestore request:
      _myProv.requestTasks();
    }
    return Page();
  }
}

I call a function from the build function in my Flutter app.
When I call notifyListeners(); from an async callback function I get the following exception:

setState() or markNeedsBuild() called during build.

My Provider:

class TechTaskProvider extends ChangeNotifier {
  ...
  void requestTasks() {
   
    CollectionReference<Map<String, dynamic>> _collection =
        FirebaseFirestore.instance
            .collection('techTasks')
            .doc(_currentTech!.uid)
            .collection('techTasks');

    _collection.get().then((s) {
        _handleResult(s);
        notifyListeners();
    });
}
  

My Trigger widget:

class Trigger extends StatefulWidget {
  const Trigger({Key? key}) : super(key: key);

  @override
  State<Trigger> createState() => _TriggerState();
}

class _TriggerState extends State<Trigger> {
  @override
  Widget build(BuildContext context) {
    MyProvider _myProv = Provider.of<MyProvider>(context);
    //
    if (isFirstRun) {
      //Set the first techincian:
      isFirstRun = false;
      // //Trigger Firestore request:
      _myProv.requestTasks();
    }
    return Page();
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白龙吟 2025-01-31 16:47:06

这样的事情应该解决问题:

class _TriggerState extends State<Trigger> {
  @override
  Widget build(BuildContext context) {
    MyProvider _myProv = Provider.of<MyProvider>(context);
    //
    if (isFirstRun) {
      //Set the first techincian:
      isFirstRun = false;
      // //Trigger Firestore request:
      WidgetsBinding.instance!.addPostFrameCallback((_) => _myProv.requestTasks());

    }
    return Page();
  }
}

Something like this should do the trick:

class _TriggerState extends State<Trigger> {
  @override
  Widget build(BuildContext context) {
    MyProvider _myProv = Provider.of<MyProvider>(context);
    //
    if (isFirstRun) {
      //Set the first techincian:
      isFirstRun = false;
      // //Trigger Firestore request:
      WidgetsBinding.instance!.addPostFrameCallback((_) => _myProv.requestTasks());

    }
    return Page();
  }
}
哽咽笑 2025-01-31 16:47:06

在更好的解决方案下方,不使用变量isfirstrun

class Trigger extends StatefulWidget {
  const Trigger({Key? key}) : super(key: key);

  @override
  State<Trigger> createState() => _TriggerState();
}

class _TriggerState extends State<Trigger> {
  @override
  void initState() {
    super.initState();
    // The below line will be executed JUST AFTER first `build` AND ONLY single time.
    WidgetsBinding.instance.addPostFrameCallback((_) => context.read<MyProvider>().requestTasks());
  }

  @override
  Widget build(BuildContext context) {
    return Page();
  }
}

Below the better solution without using variable isFirstRun.

class Trigger extends StatefulWidget {
  const Trigger({Key? key}) : super(key: key);

  @override
  State<Trigger> createState() => _TriggerState();
}

class _TriggerState extends State<Trigger> {
  @override
  void initState() {
    super.initState();
    // The below line will be executed JUST AFTER first `build` AND ONLY single time.
    WidgetsBinding.instance.addPostFrameCallback((_) => context.read<MyProvider>().requestTasks());
  }

  @override
  Widget build(BuildContext context) {
    return Page();
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文