【问题标题】: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

标签: flutter dart flutter-provider flutter-navigation


【解决方案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 方法,因此它也接收到提供者所在的构建上下文。

【讨论】:

    猜你喜欢
    • 2021-11-01
    • 2021-12-07
    • 2019-12-08
    • 2020-12-10
    • 2020-05-10
    • 2022-08-19
    • 2020-04-16
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多