skip to content

In Flutter, where do flutter_redux and signals-style packages sit on scope, boilerplate and rebuild granularity compared with BLoC and Riverpod?

level: seniorimportance: nice to knowfreq 18%

answer

  1. one store, pure reducers
  2. StoreConnector selects a view model
  3. most ceremony per change
  4. fine-grained values with tracked dependencies
  5. rebuild only what read the value

basics

~20 s

flutter_redux keeps all app state in one Store changed only by actions through pure reducers: maximum predictability and ceremony. Signals-style packages sit at the opposite end: small reactive values that track who reads them, little boilerplate, very fine-grained rebuilds.

solid answer

~40 s

`flutter_redux` 0.6 connects a `Store` from `package:redux` to widgets: `StoreProvider` (an `InheritedWidget`) exposes it, and `StoreConnector` maps the whole state to a view model, rebuilding on every store change unless `distinct` is true, in which case an equal view model skips the rebuild. All state is global, every change is an action handled by pure reducers, and middleware handles async work, which makes changes predictable and replayable but needs the most ceremony. Signals-style packages expose individual reactive values; derived values and widgets that read them are tracked automatically, so an update rebuilds only the readers, with very little code, but the structure is up to the team. BLoC sits near Redux on explicitness but per feature rather than one store; Riverpod sits between, with explicit providers and automatic dependency tracking between them.

go deeper

for a junior

Recall that Redux uses one store changed by actions through reducers, and signals-style packages use small reactive values.

for a middle

Explain StoreProvider and StoreConnector's converter, and how automatic dependency tracking limits rebuilds in signals-style state.

for a senior

Place Redux, BLoC, Riverpod and signals on explicitness versus granularity, and say which app traits would move a team toward each end.

for a principal

Judge whether predictability through ceremony or speed through implicit tracking suits the organisation, given its size, audit needs and turnover.

## Two ends of a spectrum State libraries can be placed on a line from **explicit and centralised** to **implicit and fine-grained**. Redux and signals-style packages sit at the two ends, with BLoC and Riverpod in between. ## Redux with flutter_redux Redux (via `package:redux`, connected by `flutter_redux` 0.6) follows three rules: 1. **One store** holds the entire app state as an immutable value. 2. The only way to change it is to **dispatch an action**. 3. **Pure reducers** compute the next state from the current state and the action; **middleware** intercepts actions for async work such as API calls. In Flutter: - `StoreProvider<S>` is an `InheritedWidget` that places the store in the tree. - `StoreConnector<S, ViewModel>` takes a `converter` that turns the global state into a view model, and rebuilds its `builder` on every store change unless `distinct: true` is set, which skips the rebuild when the new view model is `==` to the previous one. **Strengths:** every change is a named action, so behaviour is predictable, logging and replay are straightforward, and reducers are trivial to unit-test. **Costs:** the most ceremony per change (action, reducer case, often middleware, view model), and a single global state shape that every feature must fit into. ## Signals-style packages Signals-style libraries, which Flutter's architecture guide names among the alternatives (`package:signals`), expose **individual reactive values**: - A value holder that notifies when set. - **Derived values** computed from other values, with dependencies **tracked automatically** when they are read. - Widgets or effects that re-run only when a value they actually read changes. **Strengths:** very little code, and **rebuild granularity** as fine as a single value without hand-written selectors. **Costs:** structure is not imposed, so the team must supply conventions (where values live, who may write them); automatic tracking can make data flow harder to follow in large codebases. ## The spectrum on the leaf's criteria | Criterion | Redux | BLoC | Riverpod | Signals-style | |---|---|---|---|---| | State scope | one global store | per feature bloc | per provider, in a container | per value | | Boilerplate | highest | high | moderate | lowest | | Rebuild granularity | per connector view model | per builder, optional `buildWhen` | per watched provider, optional `select` | per read value, automatic | | Change traceability | every action named | every event named | provider updates | value writes | | Async | middleware | handlers emitting states | `AsyncValue` | team convention | ## When each fits - **Redux**: teams that already think in Redux, apps where replaying and auditing every change matters, or state that is genuinely global. - **Signals-style**: UI-heavy apps with many small independent values, teams comfortable providing their own structure. - **BLoC** and **Riverpod** cover the middle ground and are what most Flutter teams choose. ## Interview framing State the spectrum, place each library on it with one concrete mechanism (`StoreConnector`'s converter, automatic dependency tracking), and say which criterion would move you along it. That shows judgment without reciting APIs, which belong to each library's own topic.

  • In flutter_redux, how does StoreConnector avoid rebuilding on every store change?
    Its `converter` maps the whole state to a smaller view model, and with `distinct: true` it compares the new view model with the previous one and skips the rebuild when they are equal. The view model therefore needs a meaningful `==`.
  • In Flutter, what is the main risk of automatic dependency tracking in signals-style state?
    Data flow becomes implicit: a widget or derived value depends on whatever it happened to read, so tracing why something rebuilt, or which writes affect a screen, is harder than with named events or actions. Teams offset it with conventions on who may write each value.

saying these in an interview costs you the question

  • Redux in Flutter lets widgets mutate store fields directly
  • Signals-style state always requires one global store
  • StoreConnector rebuilds only the exact field that changed, automatically
  • Fine-grained reactivity removes the need for any team conventions
  • Redux has less boilerplate than signals-style packages