Home > Enterprise >  Listen to changes without caring about state in Flutter Bloc
Listen to changes without caring about state in Flutter Bloc

Time:10-22

I am currently learning how to use the Bloc state management library in Flutter, and I have a scenario where I would like to listen to an action performed (e.g. clicking a button) and react to that action in a child widget down the widget tree using a Cubit. From the documentation, it seems like the only way to rebuild child widgets is by storing a state object and reacting to changes in the state. However in my case, I don't need to store any state, I just want to know if an action has been done and react every single time it has been invoked.

Given this example below, I want WidgetB to rebuild whenever the button in WidgetA has been pressed, but I can't figure out how to construct my Cubit to allow that without storing some kind of state object.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

// What should the code be here if I don't want to store any state?
class WidgetACubit extends Cubit<void> {
  WidgetACubit({initialState}) : super(initialState);

  void doSomething() => emit(null);
}

class App extends StatelessWidget {
  App({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: BlocProvider(
          create: (_) => WidgetACubit(),
          child: WidgetA(),
        ),
      ),
    );
  }
}

class WidgetA extends StatelessWidget {
  WidgetA({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: () {
            BlocProvider.of<WidgetACubit>(context).doSomething();
            print("Something has been done");
            WidgetB.count  ;
          },
          child: const Text("Press me to do something"),
        ),
        WidgetB(),
      ],
    );
  }
}

class WidgetB extends StatelessWidget {
  static int count = 0;

  WidgetB({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<WidgetACubit, void>(
      builder: (context, state) {
        return Text("I've been rebuilt $count times");
      },
    );
  }
}

CodePudding user response:

The BlocBuilder widget works by subscribing to the Cubit's state stream. So, you will not be able to rebuild your widget using a BlocBuilder while completely circumventing the usage of any state object. You could either just use a dummy state class without any methods and properties for your Cubit's state, and emit a new instance of that whenever you call cubit.doSomething. Or you can create a custom Widget for rebuilding which you use instead of BlocBuilder.

CodePudding user response:

It is always emitting the same instance(null) that's why it wont rebuild. if you insist to rebuilt it like this, you can emit different value like

class WidgetACubit extends Cubit<void> {
  WidgetACubit({initialState}) : super(initialState);
  int count = 0;
  void doSomething() => emit(count  );
}

Btw I cannot get why do you need to use void cubit which can an event on bloc.

You can check the flutter bloccore concepts for more.

  • Related