How to "do" something if ChangeNotifier notifies with Provider Package (similar to BlocListener)?
Asked Answered
P

2

3

What I want

I have a simple model. The model extends from ChangeNotifier. If the ChangeNotifier calls notifyListeners() I want to "do" something like showing a SnackBar or Dialog. I provide the model with the Provider package to my widget tree.

What is it comparable to?

I used the flutter_bloc package before. This package offers BlocListener. With BlocListener I can "do" something on state changes. Example code:

BlocListener<BlocA, BlocAState>(
  listener: (context, state) {
    // do stuff here based on BlocA's state
  },
  child: Container(),
)

In the above example, the child will not rebuild but I can still do something depending on the state.

Is there anything comparable to the provider package? I read in the documentation of the package that ListenableProvider would give more freedom to do stuff like "animations". But I do not know if I can use this Provider in some way to show a snack bar on a notify.

Edit: I asked Remi, the author of Provider, on Twitter. With a short amount of characters, he told me that I can use didChangeDependencies for this behavior.

Pastel answered 18/12, 2019 at 21:42 Comment(0)
R
2

Please be cautious about using didChangeDependencies for this. There are only a few circumstances where didChangeDepdnencies can be used for this, and https://github.com/flutter/flutter/pull/49527 will make it impossible even in those.

The basic problem is that didChangeDepdnencies is sometimes (or, after #49527, always) called at a point where the tree is locked against state changes. Before the pull request, it is only safe on calls that are:

  • Not the first time (which is called from within a build scope)
  • Not the time where an element is being deactivated and eventually unmounted, so is no longer in a valid spot in the tree (this call will no longer happen at all after the pull request).

A safer way to do this is:

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  if (Provider.of(context).whatever == someCondition) {
    SchedulerBinding.instance.addPostFrameCallback(() {
      // show modal or dialog
    });
  }
}

This code is safer to use because it is guaranteed to run at a point where state is safe to change in the tree, rather than only working in some very specific scenarios without the frame callback.

There are probably more elegant solutions than this (such as adding a callback directly on notifyListeners for your ChangeNotifier, assuming it only fires when the tree is in a mutable state).

Runlet answered 28/1, 2020 at 22:50 Comment(0)
H
0

try using listener on your provider

final myNotifier = context.read<MyNotifier>();
void listener() {
  // Do something 
}
myNotifier.addListener(listener);
Hornblende answered 9/3, 2022 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.