I've always seen Redux Reducers very similar to the mapEventToState function of BLoC State Management. However now I notice a big difference between the two patterns and it is that the Reducers must be "pure functions" while the function mapEventToState (in many examples) can even make http request.
At this point I wonder if it is actually possible to manage mapEventToState as "pure function" adding maybe another layer of abstraction.
As I see, mapEventToState from Bloc is a merge of Reducer and Middleware layers from Redux.
In Redux, actions can be intercepted by middlewares that creates new actions (side effects) parsed by reducers. IMHO this is one of the reasons Bloc is less cumbersome and more readable than Redux.
A good idea is to extract the data layer and inject the implementation on your bloc, receiving results as futures and yielding the new states.
Related
1 I see a some times that a vuex action collects information from other vuex modules using dispatch from other modules. With this it looses its "modulair" flexibility. What is the best practise in this case?
2 Also do you agree that Vue components needs to be kept clean from alot of fetch and formcheck logic and better move this logic to vuex?
isolate the common code between 2 modules into a pure function, then import this function in both modules. You can even use a Class with static methods.
yes, Vue components should be a pure presentation/view layer - the logic must stay into reusable non-visual classes. The form validation checks are especially suitable for pure functions. And fetches could be extracted as static methods into separate Service class (or several such classes, if you want to follow the Modules pattern).
I've been using Vuex, and it's adherence to only altering state through it's mutators or actions makes me think your store should only include as flat an object as you can, with only primitives types.
Some threads even prescribe normalising your data (so instead of nested object trees you have objects with arrays of id's to indicate tree relationships). This probably matches closely to your JSON api.
This makes me think that storing classes (that may have methods to alter themselves) in your flux store is an anti-pattern. Indeed even hydrating your store's data into a class seems like you're moving against the tide unless your class performs no modifications to its internal data.
Which then got me thinking, is using any class in a Vue/Vuex/Reactive/Flux an anti-pattern?
The libraries seem explicitly designed to work with plain JS objects and the general interactions you have with the API (data in, data out) makes me feel like a more functional approach (sans immutability) is what the original designers were thinking about.
It also seems be easier to write code that runs from function => test => state mutator wrapper around function.
I understand that JS objects and JS classes behave very similarly (and are basically the same thing), but my logic is if you don't design with classes in mind, then you're more likely to not pollute your state with non-flux state changes.
Is there a general consensus in the community that your flux code should be more functional and less object orientated?
Yes. You are absolutely right in what you are thinking. State containers like Redux, Vuex are supposed to hold your data constructs and not functions. It is true that functions in JavaScript are simply objects which are callable. You can store static data on functions too. But that still doesn't qualify as pure data. It is also for this same reason that we don't put Symbols in our state containers.
Coming back to the ES classes, as long as you are using classes as POJO i.e. only to store data then you are free to use those. But why have classes if you can have simple plain objects.
Separating data from UI components and moving it into state containers has fundamental roots in functional programming. Most of the strict functional languages like Haskell, Elm, OCaml or even Elixir/Erlang work this way. This provides strong reasoning about your data flows in your application. Additionally, this is complemented by the fact that, in these languages, data is immutable. And, thus there is no place for stateful Class like construct.
With JavaScript since things are inherently mutable, the boundaries are a bit blur and it is hard to define good practices.
Finally, as a community, there is no definite consensus about using the functional way, but it seems that the community is heading towards more functional, stateless component approaches. Some of the great examples are:
Elm
ReasonML
Hybrids
swiss-element
Cycle.js
And now, even we have functional components in both Vue and React.
In the Mutations chapter, you can see an example that uses mapMutations to map mutations to component methods.
It also says that
You can commit mutations in components with this.$store.commit('xxx')
So the question comes, is committing a mutation directly from a component (not through an action) fine in vuex?
If it is, then this diagram may need to update:
Should I keep using the mapMutations method?
As far as I understood, actions are mainly used for asynchronous operations which might comprise multiple mutations. So yes, it's ok to directly use mutations, that's what they are made for. Only when you have more complex workflows involving multiple mutations you should wrap them in an action.
MapMuation is just a helper that lets you use your defined mutations (in mutation-types) as methods of your component. It is exactly the same with $store.commit but with an easier notation.
I don't know in which context your diagram is but mutations can be called from everywhere (components, services, actions, getters etc...) en will do its work finely by synchronously updating the store.
First of all: This is not an question of opinion (I'm afraid someone will flag this question), I'm interested in the technological background or the decisions for this.
That being said: Redux's store needs to be serializable. It is not allowed or frowned upon to use model classes and write their instances in the store. This is highly annoying to me. The applications logic ends up in actions or reducers where models would be a nice thing to have.
I am wondering why. What is the technological decision behind this? Why not write class instances to the store?
1) Class in instances are mutable, which leads to the same problems redux has tried to address around predictability of state by championing immutability. It also means you have to do more manual shouldComponentUpdate checks for changes if pairing with React (as references to mutated instances will be the same even if their internal state has changed)
2) Immutability makes it possible to move back and forth between states (eg during time travel debugging), something that cannot be done when mutations have occurred within instances
3) Serialisation means its very easy to persist and rehydrate the store (to/from JSON) for more advanced uses such as server side rendering and offline use
If you are interested I just wrote a more in depth answer to a similar question with an example of how it is possible to use the best of both worlds https://stackoverflow.com/a/47472724/7385246
So i am learning the flux pattern using redux as a framework for it, to generate a mobile application in react-native (no backend).I feel I have been fighting against the pattern for some time due I come from an OO background and was expecting my model to be abstracted and bind somewhere in the pattern.
Last night I think I had an epiphany by thinking that this pattern enforces the idea that all is data and how is treated in reaction to events. So is fully functional programming and no abstractions (that have state) have a place inside this pattern.
So just to map to an OO world I have explain it in this mode to my brain:
internal objects in the store: each is equivalent to the properties of a class.
Event: equivalent to the reaction to something that happen and calls methods from a class.
reducer: the methods that transform the data inside a class.
views: the representation to the user of those abstractions.
My questions then are:
Is this weird theory (models inside the store). valid or just a bad idea?
if not valid, where do my models hook in a redux based application?
if not valid, this means this pattern is just to use on the front-end?