我刚进入一个网络应用程序的Ffltter项目,所有的开发人员都在使用Ffltter提供程序进行状态管理时遇到了问题.

What is the problem
When you arrive on a screen, the variables of the corresponding provider are initialised by calling a function of the provider. This function calls an api, and sets the variables in the provider.
Problem : This function is called in the build section of the widget. Each time the window is resized, the widget is rebuilt, and the function is called again.

What we want
We want to call an api when the page is first displayed, set variables with the result, and not call the api again when the widget is rebuilt.

What solution ?

  1. 我们使用从第一个屏幕到第二个屏幕的推送.此时,我们可以调用提供程序的函数,以在第二个屏幕之前初始化提供程序. →,但第二页上的刷新将清除提供程序变量,并且不会再次调用初始化它们的函数.
  2. 我们在第二个屏幕的构造函数中调用该函数来初始化提供程序.这是一个好的图案吗?

感谢您在我的Ffltter新体验中提供的帮助:)

推荐答案

我认为你在这里混淆了几个不同的问题:

  1. 如何正确初始化提供程序
  2. 如何在初始化时调用方法(只调用一次)

关于第一个问题:

在您的main.dart文件中,您希望执行以下操作:

@override
Widget build(BuildContext context) {
  return MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (context) => SomeProvider()),
      ChangeNotifierProvider(create: (context) => AnotherProvider()),
    ],
    child: YourRootWidget();
  );
}

然后,在小部件(可能代表应用程序中的一个"屏幕")中,您需要执行类似这样的操作来使用来自该提供者的状态更改:

@override
Widget build(BuildContext context) {
  return Container(
    child: Consumer<SomeProvider>(
      builder: (context, provider, child) {
        return Text(provider.someState);
      }
    ),
  )
}

您需要执行以下操作才能访问提供程序的Mutations 状态:

@override
Widget build(BuildContext context) {
  SomeProvider someProvider = Provider.of<SomeProvider>(context, listen: false);
  return Container(
    child: TextButton(
      child: Text('Tap me'),
      onPressed: () async {
        await someProvider.mutateSomeState();
      }
    ),
  )
}

关于第二个问题……您可以(我认为)只在小部件上使用initState()方法来进行一次调用.所以...

@override
void initState() {
  super.initState();
  AnotherProvider anotherProvider = Provider.of<AnotherProvider>(context, listen: false);
  Future.microtask(() {
    anotherProvider.doSomethingElse();
  });
}

如果我做错了什么,我很抱歉.这反映了我的实现,并且运行得很好.

这里需要注意的是,我认为RiverPod可能是您真正想go 的地方(它可能更容易使用,并且有其他有用的功能,等等),但我还没有迁移到RiverPod,也没有完全弄清楚这一点.

总之..祝好运!

Flutter相关问答推荐

当MyChangeNotifier更改时如何计算函数,而无需在构建方法中进行不必要的调用- Flutter

如何使用Firebase Firestore来获取外部集合中的文档子集合中的文档

无效字符(位于字符68处)flutter—update—... europe-west1.firebasedatabase.app/

使用GO_ROUTER在模式内导航

在Flutter 中创建自定义形状

Flutter卡内容未在水平列表视图中居中

如何处理平台游戏的对象冲突?

为 flutter app/firebase 保存 chatgpt api-key 的正确方法是什么

Flutter应用无法上传到Microsoft Store

PreferredSizeWidget类不能用作混合,因为它既不是混合类也不是混合

Flutter:如何从运行时创建的列表中访问单个子部件的值

如何从底部导航栏打开 bottomModal 表?

在 Flutter 中读取 Firebase 数据库数据时遇到问题

在 Dart 中使用隔离时访问外部范围内的变量

statefulWidget 无法进行所需更改的问题

Flutter/Dart 返回_Future的实例而不是实际的字符串值

Flutter 中出现错误空判断运算符用于空值

Flutter 如何要求用户在应用程序中设置电话密码?

Flutter:如何判断嵌套列表是否包含值

我可以使用 Future 来填充Text() 小部件而不是在 Flutter 中使用 FutureBuilder 吗?