Являются ли виджеты, реализующие BLoC, обязательно StatefulWidgets?

Я новичок в шаблоне BLoC, и у меня возник вопрос, который я не смог найти в другом месте. Используя библиотеку flutter_bloc, у меня есть доступ к виджету BlocBuilder, который будет перестраиваться при изменении состояния BLoC. Поскольку я обрабатываю состояние независимо от фреймворка, необходимо ли объявлять родительский виджет (скажем, карту, содержащую данные из BLoC) как Stateful?

Мне удалось успешно реализовать BlocBuilders в качестве дочерних элементов виджетов с сохранением состояния и без сохранения состояния, но я не смог решить, какой из них будет наилучшей практикой, или будет ли вообще какой-либо случай, когда наличие состояния будет необходимо.

Думаю, я был бы на правильном пути, если бы сказал, что Stateless — это хорошо, если вам не нужно ничего обновлять за пределами BlocBuilder, но вам понадобится Stateful, если вы добавите что-то вроде RefreshIndicator и должны будете реализовать логику для этого. (и условно передавать события в BLoC). Это правильно?

Я уверен, что я слишком много объясняю здесь, но в духе этого я предоставил код ниже, если он поможет понять мой вопрос.

Вот упрощенная реализация Stateless, относящаяся к моему проекту:


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!');
          }
        }
    );
  }
}


2
0
692
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используя Bloc, вы сможете почти полностью избежать объявления виджетов с отслеживанием состояния, хотя, безусловно, возможно, а иногда и имеет смысл использовать виджеты с отслеживанием состояния или другие стратегии управления состоянием.

Если вы условно передаете логику в блок, вы можете подумать о переносе условной логики в сам блок и просто передать события, которые запускают условные операторы.

Также определенно возможно иметь несколько потоков, объявленных в блоке, и несколько StreamBuilders в пользовательском интерфейсе, прослушивающих один и тот же блок, хотя я не знаю, возможно ли это с библиотекой flutter_bloc. Похоже, вы ограничены одним потоком на блок, если используете flutter_bloc. Вместо этого вы также можете использовать стратегию/BlocProvider, описанную здесь.

Для некоторых небольших изменений в пользовательском интерфейсе, которые не оказывают никакого/сильного влияния на логику программы, может быть проще использовать виджет с состоянием для обработки состояния, чем сохранять состояние в блоке. На самом деле нет правильного или неправильного ответа для всех ситуаций, вам решать, что будет легче создавать и поддерживать в долгосрочной перспективе. Но ваша программа, вероятно, будет легче читать и легче найти то, что вы хотите изменить, если вы сохраните свою архитектуру последовательной. Итак, если вы используете блок, это будет означать обработку всего состояния в блоках и построение вашего пользовательского интерфейса полностью или почти полностью из виджетов без состояния.

Другие вопросы по теме