Artem Ash
Artem Ash
Jul 23, 2017 · 2 min read

~ An approach to further separation of concerns ~

Hi Michel. Thanks so very much for your great work on Mobx, and for this wonderful article. After reading it, I tried implementing this approach for my current project and was very pleased.

However, I’d like to second Anton Stoychev’s approach, and also offer a further clarification and suggestion around separation of concerns.

Basically, the model should function as much as possible as a state machine, and know nothing of views, routes, or anything like that. I think there should only be two things that connect the model to the outside world:

1) observable data and @computed functions that just reflect state in a clear, semantic way. eg, isDocumentDetail().
2) @actions which are of the form “setFooState” — and NOT say “showFoo()”: that is a view-related notion and we want our dependency to be as uni-directional as possible.

Likewise (and unlike in your example where the store knows how to generate a path from it’s state) the model should remain blissfully ignorant of such things as URL paths. There should then be stateFromPath() and pathFromState() functions that should *not be in the model*. Why should the model, a datastore, care about UI path’s at all? It shouldn’t, since they are part of the semantics of presentation and application : )

My convention, at least for simpler apps, is a 3-part separation of concerns:

  1. A model that contains:

a) Observable data

b) @actions that have names like setFoo(), which relate to states (and not views, *view states*)

c) @computed getter functions that define a set of states, names as isFoo(), corresponding to the actions. (though of course there can be several actions that set the same state. eg, by ID, but name, etc)

2. A router, that defines routes, and can getRouteFromState() and getStateFromRoute() (… of which the model knows nothing)

3. The React components that actually render state in a uni-directional and “stupid” way. Usually wrapped in an <App /> component that might contain <WebLayout /> and / or <MobileWebLayout />. Likewise, this knows nothing about what routes it’s rendered on (important and *not* obvious from many examples I’ve seen at least.)

I hope you find these suggestions useful. I find that they take your wonderful approach even further in the direction that you set. Thanks again for all the great work.

See my jsfiddle here https://jsfiddle.net/eheosc6g/

    Artem Ash

    Written by

    Artem Ash