BlocProvider.value与BlocProvider(create:)的区别

15

我正在使用flutter_bloc,想知道应该使用哪种方法,以及这两种方式之间有什么区别:我读到第一种方式(带有'value')时,bloc不会自动关闭,但实际上我不明白这是什么意思?

BlocProvider<LoginBloc>.value(
  value:  (LoginBloc(LoginInitialState(), AuthRepository())),
  ),

  

 BlocProvider<ProfileBloc>(
         create:  (context) => ProfileBloc(ProfileInitialState(), AuthRepository()),
       ),

即使我使用Flutter + Bloc创建了一个相当大的应用程序,我经常倾向于回到实际最佳实践的Bloc。何时使用BlocProvider.value和/或BlocProvider(create:)。如果我想到什么,我会告诉你。 - Dynamic_Pace
6个回答

22
据我理解,您需要使用以下内容:
BlocProvider.value(
  value: BlocProvider.of<BlocA>(context),
  child: ScreenA(),
);

当你已经在不同的 BlocProvider 中创建了一个 bloc,并且你只想让这个 相同的 bloc 在 widget 树的其他位置可用

我假设由于这个 bloc 不是由当前使用的 BlocProvider.value 创建的,它不会处理关闭 bloc 的操作 - 这将由原始的 BlocProvider 完成。

因此,除非你要使用的 bloc 已经存在于其他位置,否则你可以使用带有 create 方法的正常方法。


1
谢谢您的回复,但我仍然不太清楚,因为我习惯在Main函数中创建所有块,并通过BlocBuilder()或BlocProvider.of()来使用它们,所以我不明白您的想法是什么? - Osama Mohammed
@OsamaMohammed,我不太明白你的问题是什么? - matkv
所有的例子都一样,我还是卡在了如何让ScreenA()打印到UI值上面。该死,我没找到它的例子,比如ScreenA(child: Text('怎么打印这个值啊')),哈哈,我很困惑。 - Yogi Arif Widodo
也许可以重新表述一下:“当您已经在不同的BlocProvider中创建了一个bloc,并且您只想在小部件树的其他位置使用相同的bloc。” 如果您正在使用相同的小部件树,则可以仅提高bloc提供程序或从小部件树下方的上下文中读取该bloc提供程序。 - David Chopin

9
在我们的情况下,如果我们仅仅是为了传递给子组件而创建一个全新的 cubit,我们将使用以下代码:
BlocProvider<NameOfCubit>(
  ...
  child: Screen(),
)

如果我们想要使用已经创建的cubit,那么我们将通过以下方式传递它:

BlocProvider<NameOfCubit>.value(
  ...
  child: Screen(),
)

3
根据官方文档,应该使用BlocProvider来创建新的bloc,并使其在子树的其余部分中可用。在这种情况下,由于BlocProvider负责创建bloc,因此它将自动处理关闭它的操作。
BlocProvider(
  create: (BuildContext context) => BlocA(),
  child: ChildA(),
);

在某些情况下,BlocProvider 可以用于将现有的 bloc 提供给小部件树的新部分。当现有的 bloc 需要提供给新路由时,这将是最常用的。在这种情况下,BlocProvider 不会自动关闭 bloc,因为它没有创建它。
BlocProvider.value(
  value: BlocProvider.of<BlocA>(context),
  child: ScreenA(),
);

所以你用了错误的方式执行了第一种方法。


1

我想知道应该使用哪种方法,以及这两种方法之间有什么区别?

除非您不需要选择和使用已经存在的Bloc实例,否则应该使用BlocProvider(create :)。

来自package:flutter_bloc/src/bloc_provider.dart

在BlocProvider.value中不应创建新的[Bloc]或[Cubit]。始终应在[Create]函数中使用默认构造函数创建新实例。

以下代码是错误的,因为您在value中创建了LoginBloc实例:

BlocProvider<LoginBloc>.value(
  value:  (LoginBloc(LoginInitialState(), AuthRepository())),
  child: .....
  ),

但是您可以使用以下方法从上下文树的其他位置获取LoginBloc实例:

BlocProvider<LoginBloc>.value(
  value:  BlocProvider.of<LoginBloc>(context),
  child: ....
  ),

1

BlocProvider.value()不会自动关闭您的bloc,您需要通过使用dispose方法手动关闭它。


1
你能提供一个使用dispose方法手动关闭块的例子吗? - most200
你可以实例化你的 bloc。比如 ListBloc _myBloc = ListBloc(); 或者你可以在 initState() 中使用 late 关键字。然后你必须使用 BlocProvider.value 提供你的 bloc,你可以使用 dispose() 方法来关闭它。在 dispose 方法中写入:_myBloc.close(); - undefined

0
在我看来,Bloc Provider 会重置你所有的状态和事件,并再次发送一个新的 EventInitial。 另一方面,Bloc.value 不会再次发送 EventInitial。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接