【问题标题】:How to scope providers on several widgets without putting the provider on a root widget in flutter如何在几个小部件上限定提供者而不将提供者放在根小部件上
【发布时间】:2021-08-28 09:56:01
【问题描述】:

我正在做一个简单的演示,用户在其中登录、查看项目列表、单击项目,然后查看其详细信息。这是 3 个屏幕,但假设有两个流程,一个处理登录,另一个处理项目。

我正在使用provider 包管理我的状态。我在我的根小部件上放置了一个LoginRepository 提供程序,因为到处都需要这种状态。这很好用。

现在我需要一个ItemRepository,它应该在ItemListScreenItemDetailScreen 上可用。为了实现该范围,我决定创建一个名为ItemScreens 的共同祖先小部件。这是我放置我的提供者和我的嵌套Navigator的地方。

我使用Navigator.of(context) 导航我的屏幕以确保使用关闭祖先导航器。我使用Provider.of<ItemRepository>(context) 获取我的提供程序以确保使用关闭祖先状态。

这显然不起作用,因为我得到了Could not find the correct provider。我知道兄弟路由中的提供者不能被另一个兄弟访问,但我在这里嵌套导航器,我希望ItemRepository 被放置在ItemScreens,然后处理子路由,以便这两个路由可以从父路由?

旁注:
Flutter documentation 明确指出应解除提供程序以实现适当的范围界定。但我从未见过将提供程序提升到非根小部件的示例。如果我们所能做的就是将提供者放入根小部件中,那应该明确说明。

编辑:在几个小部件上重新创建提供程序是一种替代方法,但这并不是真正的范围,它只是伪值传递。

编辑:使用MultiProvider 将所有提供程序放在根小部件上并不是一个好主意,因为它会创建一个全局状态反模式。除非需要,例如用户正在访问该流程/屏幕,否则某些状态也不应该被创建。

【问题讨论】:

    标签: flutter flutter-provider flutter-navigation


    【解决方案1】:

    您可以使用 Multiprovider 将您的 MaterialApp Widget 包装在 main.dart 中,并提供您正在使用的提供者列表,这样 App 就知道将哪个类视为提供者。

    MultiProvider(
            providers: [
              ChangeNotifierProvider(
                create: (_) => FirstProvider(),
              ),
              ChangeNotifierProvider(
                create: (_) => SecondProvider(),
              ),
            ],
            child: MaterialApp(
              debugShowCheckedModeBanner: false,
              title: 'Auro',
              home: _decideMainPage(context),
              // routes: routes,
              theme: AllCoustomTheme.getThemeData(),
            ),
          )

    【讨论】:

    • 嗨,Abhinav 欢迎来到社区并感谢您的回答。我想避免将我的所有状态都放在根小部件上,因为那将是一个不可取的全局状态。我也不想创建ItemRepository,除非我已登录。例如,ItemRepository 构造函数在创建之前可能需要一个身份验证标头。
    猜你喜欢
    • 2021-01-22
    • 2021-07-04
    • 2020-08-09
    • 2019-12-31
    • 1970-01-01
    • 2021-02-20
    • 2019-12-26
    • 2020-05-19
    相关资源
    最近更新 更多