Search code examples
flutterdartstate-managementflutter-bloc

Flutter BlocConsumer react only to certain state property changes


Is it possible in Bloc, inside a BlocConsumer to only redraw a Widget when certain subset of properties of the Bloc's state change

I want the "buildWhen" in one screen to return true only if 3 props changed and in another screen i have another BlocConsumer that will be rebuilt if any property of the state changes.

My reckon so far is, I can only do this by splitting the bloc into several ones with different states.

thanks.


Solution

  • There are two approaches to achieve this.

    1. Bloc consumer with buildWhen

    We use build when to tell the bloc consumer/builder that we it needs to rebuild the widget based on specific things changed between previous and current state.

    ex.:

    BlocBuilder<TestBloc, TestState>(
      builder: (context, state) {
        return Text(
          '${state.a + state.b + state.c + state.d}',
        );
      },
      buildWhen: (previous, current) {
        return previous.a != current.a ||
            previous.b != current.b ||
            previous.c != current.c;
      },
    ),
    

    in this example widget will only be built again when a, b, or c change.

    2. BlocSelector

    BlocSelector is the widget used for listening and consuming specific parts of the bloc. So when we need to use only 3 parameters of the state we can have this example:

    BlocSelector<TestBloc, TestState, int>(
      selector: (state) {
        return state.a + state.b + state.c;
      },
      builder: (context, abcState) {
        return Text('Updated value is: $abcState');
      },
    ),
    

    These two different approaches have different use cases.

    The 1st approach (build when) is used when you want the whole state in the builder function and your widget, but you want the widget to rebuild only when certain parts of the state is changed.

    The 2nd approach (bloc selector) is used when you want to use specific parameters of the bloc for a widget render, and also this widget should not be built again if other parts of bloc get updated.