withContext<Context> method

System<State, Event> withContext<Context>({
  1. required Context createContext(),
  2. Reduce<State, Event>? reduce,
  3. ContextEffect<Context, State, Event>? effect,
  4. void dispose(
    1. Context context
    )?,
})

Adds reduce or effect into the system with a custom context.

This operator is an enhanced version of system.add, it would create a custom context when system run, we can access this context with effect callback. When system dispose, we can do clean up with it.

Usage Example

Below code showed how to register service when system run, and unregister it when system dispose:


class DisposerContext {
  
  Disposer? disposer;
}

...

system
  .withContext<DisposerContext>(
    createContext: () => DisposerContext(),
    effect: (context, state, oldState, event, dispatch) {
      if (event == null) { // event is null when system run
        final Stream<User> stream = firebaseService.currentUser;
        final subscription = stream.listen((user) {
          dispatch(UpdateUser(user));
        });
        context.disposer = Disposer(() {
          subscription.cancel();     
        });
      }
    },
    dispose: (context) {
      if (context.disposer != null) {
        context.disposer?.call();        
        context.disposer = null;        
      }
    }
  )
  ...

Implementation

System<State, Event> withContext<Context>({
  required Context Function() createContext,
  Reduce<State, Event>? reduce,
  ContextEffect<Context, State, Event>? effect,
  void Function(Context context)? dispose,
}) => runWithContext<Context>(
  createContext: createContext,
  run: (context, run, nextReduce, nextEffect, nextInterceptor) {
    final Effect<State, Event>? localEffect = effect == null ? null : (state, oldState, event, dispatch) {
      effect(context, state, oldState, event, dispatch);
    };
    return run(
      reduce: combineReduce(reduce, nextReduce),
      effect: combineEffect(localEffect, nextEffect),
      interceptor: nextInterceptor,
    );
  },
  dispose: dispose,
);