Эффективное использование блоков Flutter в нескольких виджетах: подробное руководство

Шаблон BLoC (компонент бизнес-логики) Flutter — это популярный подход к управлению состоянием, который позволяет отделить бизнес-логику от уровня пользовательского интерфейса. Одним из распространенных сценариев разработки Flutter является повторное использование одного и того же BLoC в нескольких виджетах. В этой статье мы рассмотрим различные способы достижения этой цели, предоставив разговорные объяснения и практические примеры кода.

Метод 1: создание экземпляра BLoC внутри родительского виджета
Самый простой подход — создать экземпляр BLoC внутри родительского виджета и передать его дочерним виджетам через конструктор. Вот пример:

class ParentWidget extends StatelessWidget {
  final MyBloc bloc = MyBloc();
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ChildWidget1(bloc: bloc),
        ChildWidget2(bloc: bloc),
      ],
    );
  }
}

Метод 2: использование InheritedWidget
InheritedWidget — это мощный механизм во Flutter, который позволяет распространять данные вниз по дереву виджетов. Вы можете обернуть экземпляр BLoC InheritedWidget и получить к нему доступ из любого дочернего виджета, используя BuildContext. Вот пример:

class MyInheritedWidget extends InheritedWidget {
  final MyBloc bloc;
  MyInheritedWidget({
    Key key,
    @required this.bloc,
    @required Widget child,
  }) : super(key: key, child: child);
  static MyInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }
  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) => true;
}
class ParentWidget extends StatelessWidget {
  final MyBloc bloc = MyBloc();
  @override
  Widget build(BuildContext context) {
    return MyInheritedWidget(
      bloc: bloc,
      child: Column(
        children: [
          ChildWidget1(),
          ChildWidget2(),
        ],
      ),
    );
  }
}
class ChildWidget1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = MyInheritedWidget.of(context).bloc;
    // Use the bloc instance
    return Container();
  }
}

Метод 3: Пакет провайдера
Пакет Provider — это популярное решение для управления состоянием во Flutter, которое упрощает обмен данными между виджетами. Он использует механизм InheritedWidget под капотом. Вот пример использования Provider с BLoC:

class ParentWidget extends StatelessWidget {
  final MyBloc bloc = MyBloc();
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider<MyBloc>.value(value: bloc),
      ],
      child: Column(
        children: [
          ChildWidget1(),
          ChildWidget2(),
        ],
      ),
    );
  }
}
class ChildWidget1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = Provider.of<MyBloc>(context);
    // Use the bloc instance
    return Container();
  }
}

Метод 4: пакет ScopedModel
ScopedModel — это еще один пакет, который упрощает управление состоянием во Flutter. Это позволяет вам использовать модель (например, BLoC) в нескольких виджетах. Вот пример:

class ParentWidget extends StatelessWidget {
  final MyBloc bloc = MyBloc();
  @override
  Widget build(BuildContext context) {
    return ScopedModel<MyBloc>(
      model: bloc,
      child: Column(
        children: [
          ChildWidget1(),
          ChildWidget2(),
        ],
      ),
    );
  }
}
class ChildWidget1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = ScopedModel.of<MyBloc>(context);
    // Use the bloc instance
    return Container();
  }
}

В этой статье мы рассмотрели несколько методов эффективного использования Flutter BLoC в нескольких виджетах. Будь то прямое создание экземпляра, InheritedWidget, Provider или ScopedModel, у вас есть несколько вариантов на выбор в зависимости от ваших конкретных требований. Используя эти методы, вы можете добиться большей возможности повторного использования виджетов и удобства обслуживания кода в ваших приложениях Flutter.

Помните, что выбор наиболее подходящего метода зависит от сложности вашего приложения и предпочитаемого вами подхода к управлению состоянием. Приятного кодирования!