Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible usage example #2

Open
jjwilliams42 opened this issue Oct 27, 2017 · 1 comment
Open

Possible usage example #2

jjwilliams42 opened this issue Oct 27, 2017 · 1 comment

Comments

@jjwilliams42
Copy link

I realize that you said "This is not intended for public consumption, and I will likely not maintain this", but I've looked at Redux.NET (and the umerged PR's you did), and I like the way your comment in GuillaumeSalles/redux.NET#51 (comment) composes state and reducers in Yarni. Your library also doesn't depend on IObservable (that I've seen).

I would love to see some examples of Yarni:

General Usage
Reducer Composition
State Composition
How you handle async things (calling apis)
Subscribing(?) to parts of the state

We have a WPF application that is growing unwieldy, and have been looking at alternative state management techniques.

I understand that you have no intentions of maintaining anything, but some examples would be awesome.

@cmeeren
Copy link
Owner

cmeeren commented Oct 28, 2017

I don't use Yarni anymore and haven't for a while, I've moved to F# and implemented my own store there. Still, I can give a few examples. (Sorry if they don't compile - I've only used F# for a while now.)

General Usage
Reducer Composition
State Composition

Unsure what you mean. IIRC this works exactly the same as in redux.NET.

How you handle async things (calling apis)

I do this using the listener middleware included in Yarni. I did the same thing in redux.NET, but the middleware wasn't included there. I think this is how it's used:

// A listener is essentially a function that takes an action, a state (before the action
// is sent to the reducers), and a dispatch function. For example:
class ApiListener {
  void CallApi(object action, RootState beforeState, Action<object> dispatch) {
    if (!(action is SignInRequested a)) return;
    var response = CallSignInApiWith(a.Username, a.Password);
    if (response.IsSuccessful) dispatch(new SignInSuccessful(response.AccessToken));
    else dispatch(new SignInFailed(response.Error));
  }
}

// Create the middleware
var listenerMiddleware = ListenerMiddleware.CreateMiddleware();

// Subscribe listeners
listenerMiddleware.ActionReceived += myApiListenerInstance.CallApi;

// Create store with middleware
var store = new Store(..., new[]{listenerMiddleware})

Currently (in F#, though that's irrelevant), I just use proper middleware instead of listeners, because it gives me more flexibility regarding when to pass the action down the chain, if/how to use the state before/after updating it, etc. Also it allows me to skip the concept of a "listener" and just use the existing middleware concept. Though it comes with a slightly larger chance of bugs, so YMMV.

Subscribing(?) to parts of the state

I actually made something I called ProjectingStore for this (see GuillaumeSalles/redux.NET#51 (comment) and the linked blog post). In short, it was a store implementation (or wrapper) that did not make the "raw" state available though State or StateChanged. Instead, the interface was basically this:

interface IProjectingStore<TState> {
  /// Publishes changes to the given projection of the store.
  /// Observable.DistinctUntilChanged is used so that only actual changes
  /// to the projection are published.
  IObservable<TProjection> Observe<TProjection>(Func<TState, TProjection> projection);

  /// Returns the given projection of the current state.
  TProjection Project<TProjection>(Func<TState, TProjection> projection);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants