Mobile Development 8 min read

Understanding the Dispatch Mechanism in Fish-Redux

Fish‑Redux separates UI from business logic by using a dispatch function that routes actions from a view’s handler to the component’s effect, then to the page store’s reducer, passes through any applied middleware, updates the state, and finally notifies listeners to re‑render the UI.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Understanding the Dispatch Mechanism in Fish-Redux

Fish-Redux separates UI (view) from business logic (reducer, effect) and uses a dispatch function to deliver actions from the view to the appropriate handler. This article explains how an action is progressively dispatched and processed.

Example workflow : When a user checks a todo item, the following steps occur:

GestureDetector's onTap is triggered.

The dispatch passed via buildView forwards the doneAction to the component's effect; if the effect cannot handle it, the action is passed to the page store.

The page store's dispatch invokes the reducer, which clones the state, applies the change, and returns a new state.

The store notifies listeners (e.g., _viewUpdater ) so the UI can re‑render.

Dispatch definition in Fish-Redux:

typedef Dispatch = void Function(Action action);

The actual dispatch is created inside the component's context ( DefaultContext ). The initialization code looks like this:

DefaultContext({@required this.factors, @required this.store, @required BuildContext buildContext, @required this.getState,}) : assert(factors != null), assert(store != null), assert(buildContext != null), assert(getState != null) {

During initialization, the component registers its onAction handler and creates the dispatch function:

final OnAction onAction = factors.createHandlerOnAction(this);

Then the component’s createDispatch method builds a new dispatch that first runs the effect ( onAction ) and, if not handled, forwards the action to the parent store:

Dispatch dispatch = (Action action) { final Object result = onAction?.call(action); if (result != null && result != false) return; return parentDispatch(action); };

Store dispatch implementation validates the action, runs the reducer, and notifies listeners:

final Dispatch dispatch = (Action action) { _throwIfNot(action != null, 'Expected the action to be non‑null value.'); _throwIfNot(action.type != null, 'Expected the action.type to be non‑null value.'); _throwIfNot(!isDispatching, 'Reducers may not dispatch actions.'); try { isDispatching = true; state = reducer(state, action); } finally { isDispatching = false; } _notifyListeners.forEach((listener) => listener()); };

Middleware is applied via applyMiddleware , which composes a chain of middleware functions around the original store dispatch. The composition folds the middleware list, passing each dispatch , getState , and next function:

StoreEnhancer
applyMiddleware
(List
> middleware) { return (StoreCreator
creator) => (initState, reducer) { final store = creator(initState, reducer); final Dispatch initialValue = store.dispatch; store.dispatch = middleware.map((mw) => mw(dispatch: (action) => store.dispatch(action), getState: store.getState, next: (action) => initialValue(action))).fold(initialValue, (prev, element) => element(prev)); return store; }; }

In summary, an action in Fish-Redux travels from the component’s dispatch to the effect, then possibly to the page store, through the reducer, and finally through any configured middleware before the store’s original dispatch updates the state and notifies listeners. This architecture provides clear separation, extensibility via middleware, and a transparent flow for state changes.

Flutterfish-reduxState ManagementMiddlewareDispatch
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.