reduce method

  1. @override
Future<St?> reduce()
override

The reduce method is the action reducer. It may read the action state, the store state, and then return a new state (or null if no state change is necessary).

It may be synchronous (returning AppState or null) or async (returning Future<AppState> or Future<null>).

The StoreConnectors may rebuild only if the reduce method returns a state which is both not null and different from the previous one (comparing by identical, not equals).

Implementation

@override
Future<St?> reduce() async {
  // Updates the value optimistically.
  final _newValue = newValue();
  final action = UpdateStateAction((St state) => applyState(_newValue, state));
  dispatch(action);

  try {
    // Saves the new value to the cloud.
    await saveValue(_newValue);
  } catch (e) {
    // If the state still contains our optimistic update, we rollback.
    // If the state now contains something else, we DO NOT rollback.
    if (getValueFromState(state) == _newValue) {
      final initialValue = getValueFromState(initialState);
      return applyState(initialValue, state); // Rollback.
    }
  } finally {
    try {
      final Object? reloadedValue = await reloadValue();
      final action = UpdateStateAction((St state) => applyState(reloadedValue, state));
      dispatch(action);
    } on UnimplementedError catch (_) {
      // If the reload was not implemented, do nothing.
    }
  }

  return null;
}