I would like to ask how you guys use Redux with Mantra? I’m reading bunch of articles about Smart and Dumb components by Dan Abramov which are also nicely done in Mantra as components and containers and also found set of interesting articles called “How we Redux” in Meteor app in which Abhi talks about UI state managed by Redux and Domain state (data) managed by Meteor:
I’m also confused when using Redux with Mantra, how should I go about Redux stores? Should there be one central store for all modules or each module have its own store?
P.S.: Also using webpack:webpack and React from NPM.
My impression after going to a meetup where they introduced Mantra is that you don’t use them together. Mantra has a parallel concept as what react-redux has for making container components that gets the store/dispatch and pass props/callbacks to a wrapped presentation component.
I don’t see the benefit of using both.
However, what was interesting was that in that talk, I asked the guy how he was going to test his container component because it has tracker, meteor.call and a whole lot of other injected modules that fire off at random times. He said he didn’t test that part, which was the most complicated area and prone to logic failures.
In contrast, just using Redux, I’m able to test 90% of my client side logic because they are mostly pure functions. The parts I don’t test are the trivial bits of wiring between third party components etc. I talk about my redux/testing workflow and it’s giving me some serious benefits to how I’m working.
EDIT: Just read the OP again re domain/ui state and I have alot more experience now to have a bad feeling about this. Redux is great because it keeps state simple and it keeps component updating efficient. Having another state which sometimes may be used by the react components is a bad idea, what happens if this domain state changes? Do you fire off a action to update the redux state? Why not just update the redux state in the first place.
The part which i don’t get with pure redux is where does the database stand ?
I have started using Mantra with Redux.
The react UI is trigerring Mantra actions, which are trigerring Redux actions when they want to modify the Ui State, and are doing Method calls when they want to update the database.
As always most of the (pure) functions are written (and unit tested) outside of the containers, and the container is the point where all plumbing is done (with minimal logic and only plumbing) between the UI , the commands (mantra actions) and the queries (Store.getState() for Redux, and Collections.find() for the Database).
There are indeed two sources of data for your react props, the ui state, which is handled by Redux, and the database, which is handled by Meteor. I then see the React View as the result of a (pure) transform of the database with Redux State as params.
You could probably put all needed database data in the redux store, but then it seems that your are droping reactivity altogether, and then why use Meteor in the first place ?
I have just started with this, and so i may be completely wrong, but for the moment the logic part of the code that i have been rewriting has been made very much simpler with this approach. However there is quite a lot of overhead with mantra actions calling redux actions, but i feel the need to decouple my app the more i can from all those moving technologies, and Mantra seems to fill this need.
@xunilman@smeijer that gist looks like it does exactly what I need for hooking pub/subs up with my Redux state, but I’m left scratching my head re how to use it…
@vjau this is exactly how I see Redux being used with React for a meteor frontend. No minimongo, session, reactive-dict/var and instead, using the redux store for all the above. The last piece of the puzzle was the subscriptions gist which ties it to a ddp meteor backend.
Redux encourages an architecture that decouples your events from your state from your components from your business logic from your 3rd party side effects. It handles storing all state, communication between all components, re-rendering components with changed props etc.
I’m pretty sure (haven’t used it though) Mantra is also trying to be at the architecture level which is why I see so many similarities around components (smart/dumb). I really don’t think you should be calling mantra actions with your redux actions or vice versa, sounds wrong…
You can write React components in very different ways. I think using Redux precludes you from using session, tracker (reactive dict/var), mini mongo. And I think that using Mantra integrates those above concepts, at least tracker or minimongo? This part, as I recently realised, makes the app alot harder to test.
Initially, when I was reluctantly discouraged from Blaze, I sought to learn to use React ‘the React way’. Redux grabbed my interest as a very simple, elegant solution to some initial inter-component communication but as it turns out, it solves all the other issues too so I’m at a point where I’m asking myself, why use Meteor and the answer is, I can use it on the server, but on the client, if I’m using React, I’d recommend just using Redux as a architecture.
Mantra doesn’t force you at all to use Meteor.
Mantra is a pattern, that use two technologies : React-komposer, that allow you to build Containers out of asynchronous (callback) data sources (be it Meteor, Redux, Promises, and probably all you can imagine), and React simple di, which allows you to organize your project with dependency injection, hence making it easy to unit test.
I don’t see why it should be harder to test a Mantra application since the integration point (the container building) use composition and dependency injection which are the two patterns allowing easy unit testing.
I have not personnally tested integration testing at this point with mantra but i suppose it must be relatively easy to compose at will the parts you want to work upon in your test.
So if you use Redux, you’d use react-redux which gives you redux containers.
Redux is actually not dependent on React. So I’m also thinking of using it on the server-side at some point. It’s a great way to make your state changes more predictable.
Redux only uses two things:
The state of the application
A function that handles changes to the state (actions)
My components will only ever take in two things:
A substate of the application
List of functions that triggers actions
If you need async behaviour, you’d use redux-thunk which is just a fancy word for async actions. The whole codebase is about 10 lines of code.
I confused mantra with komposer. I don’t think you should use Komposer with React-redux which also composes data for components. You could probably use Komposer with just Redux.
With this pattern, I don’t see where you need DI. I’ve been doing quite a bit of testing, albeit not exactly unit testing, but because everything is pure functions, testing is just setting up the test data, passing it into the test functions and seeing the outputs.
I know this is almost 30 days old which in the JS world is ancient… but in my mind, there are benefits from both Mantra and Redux that could be mutually exclusive. Adding Meteor into the mix provides a 3rd layer that again has potentially mutually exclusive benefits.
I have seen several examples and kick starts that have (sometimes large) data on the client in both the Meteor (minimogo) memory space and the state memory space at the same time. That definitely seems like a bad thing to me. It seems like Meteor is the master for subscription data, so let it - and only it - handle data that via containers (the choice of container is up to you).
Mantra seems (so far) to be the master of application architecture and/or workflow. It allows for controlling load order, routing, consistent module and application structure, and context(s) in a very concise way. While it also provide a recommended way to handle actions/state - this is where I’d question if Redux might not be a better alternative.
For (Meteor) methods and other actions - these tend to often be tied directly to application state (e.g. what is the current filter being passed from the UI). This leads to the questions of who should handle application state and how. Redux seems to be the master there so it might make sense to have a way for telling mantra to use Redux actions/state instead of Mantra’s defaults.
The killer questions though seem to be how do I glue all these pieces together in a way that make sense while still cover application wide concerns such as authentication and handling hooks (side effects), and so on…
The mantra docs are also really just small samples of a subset of the available API’s so that doesn’t help make things any easier. However I am hopefully not the only one working on gluing all this together in way that makes sense and hoping none of the pieces change too much in the interim. I’ll certainly share my finding and hopefully as some already have, so will others. It would help us all if the brilliant minds that delivered some of the key players could lend a hand too though or at least invest as much time in making great things work better together as some do in trying to prove who’s is superior.