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

时间:2019-04-08 16:33:27

标签: dart flutter bloc

我是BLoC模式的新手,并且出现了一个问题,我无法在其他地方找到。使用flutter_bloc库,我可以访问BlocBuilder小部件,该小部件将在BLoC状态发生变化时重新生成。 由于我处理的状态独立于框架,因此是否有必要将父小部件(例如,包含来自BLoC的数据的Card)声明为有状态?

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

我想如果您不需要在BlocBuilder之外进行任何更新,可以说Stateless很好,但是如果要添加诸如RefreshIndicator之类的东西并且必须实现,则需要Stateful逻辑(并有条件地将事件传递给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!');
          }
        }
    );
  }
}


1 个答案:

答案 0 :(得分:2)

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

如果要有条件地将逻辑传递给块,则可能要考虑将条件逻辑移到块本身,而只需传递触发条件的事件。

当然也可以在bloc中声明多个Stream,并在UI中侦听同一个Bloc的UI中具有多个StreamBuilder,尽管我不知道flutter_bloc库是否可行。如果您正在使用flutter_bloc,则似乎每个块只能使用一个Stream。您也可以改用here中描述的strategy / BlocProvider。

对于用户界面中的一些小变化,该变化不影响程序的逻辑,使用有状态的小部件处理状态要比将状态保留在Bloc中容易。并非在所有情况下都存在正确或错误的答案,而是由您决定从长远来看,哪些内容更易于构建和维护。但是,如果保持体系结构一致,您的程序可能会更易于阅读和查找想要更改的内容。因此,如果您使用的是bloc,则意味着要处理Blocs中的所有状态,并完全或几乎完全使用无状态小部件来构建UI。