使用提供者值颤振初始路由

Posted

技术标签:

【中文标题】使用提供者值颤振初始路由【英文标题】:Flutter initial route using provider value 【发布时间】:2020-12-24 23:16:26 【问题描述】:

我刚开始使用 provider 作为 Flutter 的状态管理。我在提供程序中有一个值用于初始登录。 isLogin 将返回 true 或 false 并根据它将用户重定向到主页或登录页面。我收到以下错误:

在这个 MyApp Widget 上方找不到正确的 Provider

另外,这是进行身份验证的好方法还是有更好的方法。我正在使用 laravel API 进行身份验证。

Main.dart

void main() 
  runApp(MyApp());


@override
Widget build(BuildContext context) 
  return ChangeNotifierProvider<UserProvider>(
      create: (context) => UserProvider(),
      child: MaterialApp(
      initialRoute:Provider.of<UserProvider>(context,listen:false).isLogin?'/':'/login',
      routes: 
        '/':(_)=>HomePage(),
        '/donation-history':(_)=>DonationHistoryPage(),
        '/login':(_)=>LoginPage(),
        '/new-donation':(_)=>NewDonation()
      ,
      debugShowCheckedModeBanner:false,
      title: 'RedHero',
      theme: ThemeData(
        primaryColor: kPrimaryColor,
        accentColor: Colors.white,
        scaffoldBackgroundColor: kBackgroundColor,
        fontFamily: "Poppins",
        textTheme: TextTheme(
          bodyText1: TextStyle(color: kBodyTextColor)
        )
      ),
    ),
  );

【问题讨论】:

没关系,但是我最初的问题呢?我找不到错误,我检查了小部件树,并且提供程序位于我所有路线的顶部@Uni 上面的小部件属于MyApp @Uni 【参考方案1】:

破碎的图案是:

class OuterWidget : StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return ChangeNotifierProvider<Something>(
      ... Provider.of<Something>(context) ...
    );
  

问题在于Provider.of&lt;Something&gt; 收到的context 与传递给build 函数的context 相同。在这种情况下,ChangeNotifierProvider 不存在;提供者仅添加到后代构建上下文中,这些构建上下文是在构建子小部件时创建的。

如果不清楚,想象一下将提供的对象提取到一个变量中(这不会改变代码的含义):

class OuterWidget : StatelessWidget 
  @override
  Widget build(BuildContext context) 
    final something = Provider.of<Something>(context);
    return ChangeNotifierProvider<Something>(
      ... something ...
    );
  

现在很明显,我们正在尝试使用尚未提供的对象。

因此,一种解决方案是将内部部分拆分为单独的小部件:

class OuterWidget : StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return ChangeNotifierProvider<Something>(
      ... InnerWidget() ...
    );
  


class InnerWidget : StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return ... Provider.of<Something>(context) ...;
  

此小部件将接收一个新的子上下文,提供者确实存在于该上下文中。

另一种解决方案是使用Consumer widget,它恰好适用于这种情况:

class OuterWidget : StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return ChangeNotifierProvider<Something>(
      ...
      Consumer<Something>(builder: (_, something, __) => ... something ...)
      ...
    );
  

现在,Consumer 的子代的构建被延迟到 builder 方法,因此它也接收到提供者所在的构建上下文。

【讨论】:

以上是关于使用提供者值颤振初始路由的主要内容,如果未能解决你的问题,请参考以下文章

从firestore颤振提供程序中的db收集数据时如何初始化一个类

如何使用颤振提供程序从 Firestore 获取数据?

在颤振应用程序中坚持与 sqflite 的提供商集成

颤振 - supabase 密码恢复

在颤振中使用提供者时,getter 被调用为 null

如何使用颤振提供者监听列表中的变化?