简体   繁体   English

Flutter 提供者 state 未在消费者小部件中更新

[英]Flutter provider state not updating in consumer widget

I'm trying to set state using provider across pages.我正在尝试跨页面使用提供程序设置 state 。 but its not changing.但它没有改变。

I have added the changeNotifierProvider in the main.dart main.dart我在 main.dart main.dart 中添加了 changeNotifierProvider

    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            ChangeNotifierProvider(builder: (context) => GlobalState())
          ],
        child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            routes: {
              '/': (context) => HomePage(),
              '/products': (context) => ProductsPage()
            }
          )
        );
      }
    }

I am trying to set and get a simple name string我正在尝试设置并获取一个简单的名称字符串

globatState.dart globatState.dart

    class GlobalState extends ChangeNotifier{
      String _name = 'Hello';
      String get getName => _name;
      void setName(String value){
        _name = value;
        notifyListeners();
      }
    }

In the home page I am setting the state and can move to products page using navigator pushNamed route.在主页中,我正在设置 state 并且可以使用导航器 pushNamed 路由移动到产品页面。

homepage.dart主页.dart

    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context){
        GlobalState gs = GlobalState();
        return Scaffold(
          appBar: AppBar(title: Text('Home'),),
          body: Container(
            child: Column(children: <Widget>[
              RaisedButton(onPressed: ((){
                gs.setName('World');
                }),
                child: Text('Set data'),
              ),
              RaisedButton(
                onPressed: () => Navigator.pushNamed(context, '/products'),
                child: Text('Products'),
              ),
            ],)

          ),
        );
      }
    }

In the products Page I'm using consumer to get the state productsPage.dart在产品页面中,我使用消费者来获取 state productsPage.dart

    class ProductsPage extends StatelessWidget{
      @override
      Widget build(BuildContext context){
        return Scaffold(appBar: AppBar(title: Text('Products'),
        ),
        body: Container(child:Column(children: <Widget>[
          Text('This is the productPage'),
          Container(
            child:Consumer<GlobalState>(
              builder: (context, gs, child){
                return Text('this is the data: ${gs.getName}');
              },
            )
          )
        ],))
        );
      }
    }

But in the products page I'm only getting the initial value of the state not the changed one.但是在产品页面中,我只获得了 state 的初始值,而不是更改后的值。 Am I missing something or I am navigating the wrong way?我是否遗漏了某些东西,或者我的导航方式错误?

GlobalState gs = GlobalState();

will create a new instance of your GlobalState class.将创建您的 GlobalState class 的新实例。 Which is not registered as a provider.未注册为提供商。

Instead, use the instance provided by provider like this相反,像这样使用提供者提供的实例

GlobalState gs = Provider.of<GlobalState>(context, listen:false);
gs.setName('world');

Try using the equatable package on pub.dev, link below ->尝试在 pub.dev 上使用 equatable package,链接如下 ->

https://pub.dev/packages/equatable https://pub.dev/packages/equatable

You can extend a class from Equatable and then inside the class you can override the getter props with all the properties/member variables of the class.您可以从 Equatable 扩展 class,然后在 class 中,您可以使用 class 的所有属性/成员变量覆盖 getter 道具。

This happens because when your data gets updated from the data source (REST APIs) due to performance optimisation techniques that Flutter uses, it does not compare every property/member variable inside your class instance, it refers to the object's location in memory only.发生这种情况是因为当您的数据由于 Flutter 使用的性能优化技术而从数据源(REST API)更新时,它不会比较 class 实例中的每个属性/成员变量,它仅指对象在 ZCD69B4957F06CD8191ZBFDE3 中的位置。 Using equatable you can essentially override the == operator and hashCode for every object of the class in memory and it will compare the old value for every defined property in the props getter variable to the new value and if any property does not match, then it will overwrite it and then your provider/consumer will update the UI and it will reflect the updated state.使用 equatable 您基本上可以为 memory 中的 class 的每个 object 覆盖 == 运算符和 hashCode,它会将旧值与属性中每个已定义属性的旧值进行比较将覆盖它,然后您的提供者/消费者将更新 UI,它将反映更新的 state。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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