实现 BLoC 的小部件是否一定是 StatefulWidgets?

Are widgets implementing BLoCs necessarily StatefulWidgets?

我是 BLoC 模式的新手,出现了一个我在其他地方找不到的问题。使用 flutter_bloc 库,我可以访问一个 BlocBuilder 小部件,只要 BLoC 的状态发生变化,它就会重建。 由于我正在处理独立于框架的状态,是否有必要将父小部件(比如包含来自 BLoC 的数据的卡片)声明为有状态的?

我已经能够成功地将 BlocBuilders 实现为有状态和无状态小部件的子级,但我无法决定哪种是最佳实践,或者是否存在任何情况下是有状态的将是必要的。

如果您不需要更新 BlocBuilder 之外的任何内容,我想我会说无状态很好,但是如果您要添加类似 RefreshIndicator 的东西并且有为此实现逻辑(并有条件地将事件传递给 BLoC)。 对吗?

我确定我在这里解释过度了,但本着这种精神,我在下面提供了一些代码,如果它有助于理解我的问题。

这是一个与我的项目相关的简化的无状态实现:


class WeatherCard extends StatelessWidget {

  /// You can assume that the following is happening:
  ///   1) There is a BlocProvider in the parent widget which
  ///      will implement this WeatherCard.
  ///
  ///   2) The WeatherLoaded state in the WeatherBloc provides an 
  ///      instance of a WeatherModel which contains all of the data
  ///      from a weather API.
  ///

  @override
  Widget build(BuildContext context) {
    return Card(
      child: BlocBuilder(
        bloc: BlocProvider.of<WeatherBloc>(context),
        builder: (BuildContext context, WeatherState state) {
          if (state is WeatherLoading) {
            return Text('Loading...');
          } else if (state is WeatherLoaded) {
            return Text(state.weatherModel.temp.toString());
          } else {
            return Text('Error!');
          }
        }
    );
  }
}

以及状态实现:


// You can make the same assumptions here as in the Stateless implementation.

class WeatherCard extends StatefulWidget {
  @override
  _WeatherCardState createState() => _WeatherCardState();
}

class _WeatherCardState extends State<WeatherCard> {
  @override
  Widget build(BuildContext context) {
    return Card(
      child: BlocBuilder(
        bloc: BlocProvider.of<WeatherBloc>(context),
        builder: (BuildContext context, WeatherState state) {
          if (state is WeatherLoading) {
            return Text('Loading...');
          } else if (state is WeatherLoaded) {
            return Text(state.weatherModel.temp.toString());
          } else {
            return Text('Error!');
          }
        }
    );
  }
}


通过使用 Bloc,您应该能够几乎完全避免声明有状态小部件,尽管这当然是可能的,有时使用有状态小部件或其他状态管理策略也是有意义的。

如果您有条件地将逻辑传递给 bloc,您可能需要考虑将条件逻辑移至 bloc 本身,并只传递触发条件的事件。

当然也可以在 bloc 中声明多个 Streams,在 UI 中声明多个 StreamBuilder 监听同一个 Bloc,尽管我不知道 [=21= 是否可行] 图书馆。如果您使用 flutter_bloc,您似乎被限制在每个 bloc 中只能使用一个 Stream。您也可以使用 strategy/BlocProvider 描述的 here 代替。

对于 UI 中的一些不 any/much 影响程序逻辑的小改动,使用有状态小部件来处理状态可能比将状态保持在集团。对于所有情况并没有真正正确或错误的答案,由您决定在长期 运行 中什么更容易构建和维护。但是如果您保持体系结构一致,您的程序可能会更易于阅读并且更容易找到您想要更改的内容。因此,如果您使用的是 bloc,那将意味着处理 Bloc 中的所有状态并完全或几乎完全使用无状态小部件构建您的 UI。