【问题标题】:StreamProvider returns no data when used with Navigator与 Navigator 一起使用时,StreamProvider 不返回任何数据
【发布时间】:2021-10-12 15:32:12
【问题描述】:

问题是我没有从 Authenticated 路由中的 StreamProviders(在全局级别定义)中获取任何值:

  runApp(MultiProvider(
    providers: [
      Provider.value(value: userService),
      StreamProvider.value(value: authService.userStream, initialData: null),
      StreamProvider.value(value: userService.userDataStream),
      StreamProvider.value(value: userService.characterStream),
    ],
    child: MyApp(),
  ));
}

我注意到这与我的 Navigator 的逻辑有关(如果我删除它,提供程序值会按预期向下传递到小部件树)。我使用的 Navigator 基于应用程序具有 3 个状态的想法:Not AuthenticatedAuthenticatedAuthenticated-First-Time。我得到了我是否从loginStream 认证的值(到目前为止一切正常):

@override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: loginStream,
      builder: (ctx, snapshot) {
        if (!snapshot.hasData) return Loading();
        LoginState state = snapshot.data;
        if (state == LoginState.LOGGED_OUT) return LoginScreen();
        if (state == LoginState.FIRST_TIME) return CharacterCreationScreen();
        return Navigator(
          key: navigatorKey,
          initialRoute: "/home",
          onGenerateRoute: (settings) => PageRouteBuilder(
            pageBuilder: (ctx, _, __) => routes(settings)(ctx),
            transitionsBuilder: pageTransition,
          ),
        );
      },
    );

问题是,如果我已通过身份验证并在 HomeScreen 中显示,那么即使有可用的实际数据,userDataStreamcharacterStream 都会返回 null。如果我删除 StreamBuilder + LoginLogic 本身并只返回上面的 Navigator 小部件,那么 HomeScreen 将获得正确的值。

更新: 我注意到它甚至不是 StreamBuilder。如果我在构建器中删除了 3 个 if,则流值会正确传播。不知道为什么会这样。

【问题讨论】:

    标签: flutter flutter-provider


    【解决方案1】:

    我不太确定这是否有帮助,因为我缺乏细节,但这是我目前注意到的:

    1. 如果您是第一次在 multiprovider 中创建对象,则不应使用 .value - 检查这是否适用。
    2. 尝试清理 StreamBuilder 函数体中的 if 语句(使用 if、else if 和 else 关键字。

    此外,根据您的描述,听起来好像只要 if 语句为真,返回并因此取消构建的函数体,流就会以某种方式重置并默认为 null。也许调查一下并更新您的问题。

    【讨论】:

    • 嘿,.value 应该是正确的做法,因为我正在重用已经初始化的值。我确实尝试过创建,但这也不起作用。清理 if 语句不起作用 :( 是的,如果 if 语句为真,它会以某种方式重置流(我不从 if 分支读取流)
    【解决方案2】:

    改变这个

      Provider.value(value: userService),
      StreamProvider.value(value: authService.userStream, initialData: null),
    

    到这里

    Provider(create: (context) => userService)
    StreamProvider(create:(context) => authService.userStream, initialData: null),
    

    对您注册的所有提供商执行相同操作

    要公开新创建的对象,请使用提供者的默认构造函数。如果要创建对象,请不要使用 .value 构造函数,否则可能会产生不希望的副作用。 https://pub.dev/packages/provider

    【讨论】:

    • 不,不幸的是,这没有帮助。我传递的值也已经初始化,这让我相信.value 无论如何都是正确的方法。虽然又试了一次,但没有运气
    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 2017-12-27
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多