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

问题描述

我刚刚开始使用提供程序作为扑动的状态管理。我在提供程序中有一个值可用于初始登录 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)
        )
      ),),);
}

解决方法

断开的模式是:

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方法为止,因此该方法还将接收提供者所在的构建上下文。