簡體   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