使用提供者值颤动初始路线

时间:2020-09-06 08:33:39

标签: flutter dart flutter-provider flutter-navigation

我刚刚开始使用提供程序作为扑动的状态管理。我在提供程序中有一个值可用于初始登录。 isLogin 将返回true或false,具体取决于它将用户重定向到主页还是登录页面。我收到以下错误:

在此MyApp窗口小部件上方找不到正确的提供程序

此外,这是进行身份验证的好方法还是有更好的方法?我正在使用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)
        )
      ),
    ),
  );
}

1 个答案:

答案 0 :(得分:1)

断开的模式是:

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

问题是Provider.of<Something>收到传递给context函数的相同build。在这种情况下,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方法为止,因此该方法还将接收提供者所在的构建上下文。