Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

flutter - ChangeNotifierProvider vs ChangeNotifierProvider.value

I am quite new to this framework and working on state management using provider package where I come across ChangeNotifierProvider and ChangeNotifierProvider.value, but I am unable to distinguish their use case.

I had used ChangeNotifierProvider in place of ChangeNotifierProvider.value, but it doesn't work as intended.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Let's take this in steps.

What is ChangeNotifier?

A class that extends ChangeNotifier can call notifyListeners() any time data in that class has been updated and you want to let a listener know about that update. This is often done in a view model to notify the UI to rebuild the layout based on the new data.

Here is an example:

class MyChangeNotifier extends ChangeNotifier {
  int _counter = 0;
  int get counter => _counter;

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

I wrote more about this in A beginner’s guide to architecting a Flutter app.

What is ChangeNotifierProvider?

ChangeNotifierProvider is one of many types of providers in the Provider package. If you already have a ChangeNotifier class (like the one above), then you can use ChangeNotifierProvider to provide it to the place you need it in the UI layout.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyChangeNotifier>(        // define it
      create: (context) => MyChangeNotifier(),              // create it
      child: MaterialApp(
        ...

          child: Consumer<MyChangeNotifier>(                // get it
            builder: (context, myChangeNotifier, child) {
              ...
                  myChangeNotifier.increment();             // use it

Note in particular that a new instance of the MyChangeNotifier class was created in this line:

create: (context) => MyChangeNotifier(),

This is done one time when the widget is first built, and not on subsequent rebuilds.

What is ChangeNotifierProvider.value for then?

Use ChangeNotifierProvider.value if you have already created an instance of the ChangeNotifier class. This type of situation might happen if you had initialized your ChangeNotifier class in the initState() method of your StatefulWidget's State class.

In that case, you wouldn't want to create a whole new instance of your ChangeNotifier because you would be wasting any initialization work that you had already done. Using the ChangeNotifierProvider.value constructor allows you to provide your pre-created ChangeNotifier value.

class _MyWidgeState extends State<MyWidge> {

  MyChangeNotifier myChangeNotifier;

  @override
  void initState() {
    myChangeNotifier = MyChangeNotifier();
    myChangeNotifier.doSomeInitializationWork();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyChangeNotifier>.value(
      value: myChangeNotifier,                           // <-- important part
      child: ... 

Take special note that there isn't a create parameter here, but a value parameter. That's where you pass in your ChangeNotifier class instance. Again, don't try to create a new instance there.

You can also find the usage of ChangeNotifierProvider and ChangeNotifierProvider.value described in the official docs: https://pub.dev/packages/provider#exposing-a-value


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...