繁体   English   中英

如何在两个不同的路由(屏幕)之间正确设置 BlocProvider?

[英]How to set correctly the BlocProvider between two different routes (screens)?

我正在为我的应用程序使用Bloc ,但是我做错了什么,也就是说,提供了在MaterialApp中创建的所有 BlocProvider,我不想遵循这种不好的做法。

假设当我导航到ScreenA时,我们按如下方式创建Bloc

      case PageNames.screenA:
        return PageTransition( // Some class that navigates
          duration: const Duration(milliseconds: 400),
          child: BlocProvider<ScreenABloc>(
            create: (context) => ScreenABloc(),
            child: const ScreenAPage(),
          ),
      );

现在在ScreenA内,我将导航到ScreenB ,一切都很好,但是在我的小部件树底部的ScreenB内,我想再次访问ScreenABloc ,但我无法分配BlocProvider.value因为我得到:

ProviderNotFoundException (Error: Could not find the correct Provider<ScreenABloc> above this Welcome Widget

return BlocProvider.value(
      value: BlocProvider.of<ScreenABloc>(context),
      child: child ...
);

所以我不确定如何获得已经创建的供应商,或者我是否应该重新创建它或者在这些情况下该怎么做。

您可以在屏幕本身中创建一个创建BlocProvider的方法,然后您可以使用该方法为您导航和创建提供者。

这是一个例子:

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

   static Widget create() {
    return MultiBlocProvider(
      providers: [
        BlocProvider<SignInBloc>(
          create: (BuildContext context) => SignInBloc(),
        ),
      ],
      child: const SignInScreen(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

推送新路线时,您应该使用BlocProvider.value

/// declare the bloc
final _screenABloc = ScreenABloc();

然后在ScreenAScreenB中使用它

case PageNames.screenA:
  return PageTransition( // Some class that navigates
    duration: const Duration(milliseconds: 400),
    child: BlocProvider.value(
      value: _screenABloc,
      child: const ScreenAPage(),
    ),
  );

case PageNames.screenB:
  return PageTransition( // Some class that navigates
    duration: const Duration(milliseconds: 400),
    child: BlocProvider.value(
      value: _screenABloc,
      child: const ScreenBPage(),
    ),
  );

在文件开头使用所有BlocProviders并不总是被认为是不好的做法。 根据官方文档

默认情况下, BlocProviderlazily创建 bloc,这意味着创建将在通过 BlocProvider.of(context) 查找 bloc 时执行。


  • 那么现在,在全球范围内使用providers的用例是什么?

    当您想访问应用程序中几乎所有位置的提供商时。

  • 什么时候使用通过路由的providers

    当只有一些屏幕需要访问bloc时,您可以使用BlocProvider.value传递值


根据BlocProviderflutter_bloc的官方文档,按照以下步骤将BlocProvider传递给子屏幕。

创建BlocA()

BlocProvider(
  lazy: false,
  create: (BuildContext context) => BlocA(),
  child: ChildA(),
);

BlocA的值传递给ScreenA()

确保这是从ChildA()内部调用的

BlocProvider.value(
  value: BlocProvider.of<BlocA>(context),
  child: ScreenA(),
);

现在从ChildAScreenA检索值如下:

// with extensions
context.read<BlocA>();

// without extensions
BlocProvider.of<BlocA>(context);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM