简体   繁体   中英

Why Provider.of<> doesn't work without `listen: false`?

I've simple widget tree, and try to figure out why Provider.of<>() doesn't work in the GestureDetector, onTap() callback.

This is my model:

class ShareObject {
  int intField;

  ShareObject(this.intField);
}

class ShareObjectProvider extends ShareObject with ChangeNotifier {
  ShareObjectProvider(super.intField);

  void increment() {
    intField++;
    notifyListeners();
  }
}

Here is my simple tree, where I try to invoke method from model:

class ParentWidgetState extends State<ParentWidget> {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => ShareObjectProvider(0),
      child: Scaffold(
        body: const WidgetThree(),
      ),
    );
  }
}

class WidgetThree extends StatelessWidget {
  const WidgetThree({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
        width: 200,
        height: 200,
        child: Container(
          color: Colors.deepOrange,
          child: Center(
              child: GestureDetector(
                onTap: () =>
                    {Provider.of<ShareObjectProvider>(context).increment()},
                child: Text(
                  "Test ${Provider.of<ShareObjectProvider>(context).intField}",
                  style: const TextStyle(color: Colors.blueAccent),
                ),
            )
          ),
        ),
      ),
    );
  }
}

Why when I change to Provider.of<ShareObjectProvider>(context, listen: false).increment() it start working correctly?

Your syntax is not good for provider. you need to add listen: true OR listen: false.

Provider.of<ShareObjectProvider>(context, listen: false).increment()

As per documentation,

Provider.of<T>(context)

works like a watch, which makes the widget to rebuild again

listen: false

makes it work like read

in your case:

late ShareObjectProvider provider;


void initState() {
  super.initState();

  provider = Provider.of<ShareObjectProvider>(listen: false);
}

then use it in your GestureDetector

here's the link for provider's documentation where the above said things are mentioned

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM