What's the difference: BlocBuilder & buildWhen vs BlocSelector
Asked Answered
B

1

9

I'm looking at the comment docs

/// An optional [buildWhen] can be implemented for more granular control over
/// how often [BlocBuilder] rebuilds.
/// [buildWhen] should only be used for performance optimizations as it
/// provides no security about the state passed to the [builder] function.
/// [buildWhen] will be invoked on each [bloc] `state` change.
/// [buildWhen] takes the previous `state` and current `state` and must
/// return a [bool] which determines whether or not the [builder] function will
/// be invoked.

and

/// The [selector] function which will be invoked on each widget build
/// and is responsible for returning a selected value of type [T] based on
/// the current state.
final BlocWidgetSelector<S, T> selector;

And it reads to me like in case of buildWhen the check will be performed all the time, while the rebuilt won't happen if it returns false.

In the Selector case it reads like the build method will be called every time, but the state will be the same if the selector returns same result.

This does not really add up to what I'm seeing when debugging the code, when the builder is only called when the Selector state changes, same as when buildWhen returns true.

So what are the actual differences in this 2 approaches? Are there any at all except for the syntax?

Bricebriceno answered 31/7, 2022 at 15:43 Comment(2)
Any luck? From my end I submitted an issue hereTreed
Explanations can be found in the author's comment on the PR of the feature itself: github.com/felangel/bloc/pull/2621#issuecomment-886867055. Technically BlocBuilder.buildWhen and BlocSelector can do the same thing but differ in their use cases (before reading the PR comment, it was not obvious to me either).Immitigable
L
2

Both BlocSelector and BlocBuilder 's purpose is return a Widget only depends on a small part of the state

BlocSelector allows to filter updates by selecting a new value based on the current bloc state:

BlocSelector<LoginBloc, LoginState, String>(
  selector: (LoginState state) => state.username,
  builder: (context, String username) {
    // Build widget based on `username` of LoginState
    // This builder only call when state.username change
  },
);

BlocBuilder doesn't has the filter function, it only has the condition function to decide builder function to run or not

BlocBuilder<LoginBloc, LoginState>(
  buildWhen: (previousState, state) => previousState.username != state.username,
  builder: (context, state) {
    final username = state.username;
    // This builder only call when state.username change
  },
);

They have the same goal, but I think BlocSelector is more clear in its goal than BlocBuilder, and it saves a bit of code, too.

Lusatia answered 20/9, 2023 at 1:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.