I went through the egghead videos on Redux but I’m still confused when it comes to using Redux in Meteor.
Are we supposed to store the data from Mongo in Redux? Or just UI state? Does anyone have a working example of using Redux with Meteor that actually uses Mongo to persist?
Whatever makes sense for your app. The easiest path is to only use it for local UI state.
However, if you’d like you can also listen for changes on the a collection and when they change, you can sync the current state of minimongo to a redux array. This means whenever data comes in from a publications your redux store is synced and react-redux can update the UI as needed. As the post above says, that repo will show you how to use the flux-helpers package to listen for changes and dispatch an action to sync.
The downside is that it’s more wiring, but you get more control, better performance, and de-coupling.
Yeah, I think Adam’s right in that Redux is primarily for UI state. A good example being a state like “MODAL_OPEN”. Meteor apps are very data driven, so you’ll end up seeing that your redux store is pretty barebones. Even so, I think it’s a great pattern due to the middle wares and tools it comes with. One thing to remember is Domain State, the data you store in mongo, is different than UI state…but you can interface with updating it through “redux-thunk”. Essentially the UI state store dispatches actions to change UI state and dispatches functions (side effects) to deal with domain state updates.
Yeah since posting this I saw something @SkinnyGeek1010 wrote about relay being for domain state and redux for UI state. All the contradiction is confusing me now though
Yeah since our relay is meteor live query and tracker, treat that the same way as react developers treat relay. The truth is, redux may be overkill to some people in Meteor. And there’s 1000000 opinions. If you like Dan abramov the creator, the concept of the project, then make it work in the meteor context. It just won’t be 100% as other redux users will be implementing it.
I’m also really confused as to how Redux might work in a Meteor application.
For the sake of learning, here’s a branch I made from @SkinnyGeek1010 's Redux example. ( thanks skinnygeek). This branch uses only Meteor Methods and not pub/sub. One thing I noticed is you can have optimistic UI updates without Minimongo, example here. On an update event, let the reducer set the store as soon as an action happened, and also call the method. If the method returns an error the change will be reverted.
Is this approach manually doing some of the heavy lifting that Minimongo/Tracker provides out of the box?
One other aspect I’m confused about using Redux is the connect function provided by the optional add-on package called React-Redux. Checking out the source code it seems like the connect function’s main purpose is to diff a component’s current state with the new incoming state, and only render if necessary. This sounds similar to descriptions of Blaze functionality, is it ?
Without using the optional React-Redux library what happens? ( I wanted to try this as well in the example branch ).
Yes, it does, as explained in the project’s readme file. Anyway, I like the ideia of having a single source of truth within a ReactiveDict and how it is mutated by actions/dispatching. Also, avoids Session abuse.
Yea even in the React community there is debate about where flux fits in. Eventually Relay may include transient state (local UI state), which would eliminate Redux.
However, even in my React Native app, Relay is too complex to bother. Using AJAX, a REST API, and Redux gets the job done.
For what it’s worth I delayed using Redux until I had too (by using container compoennts to fetch via AJAX and pass props down), but at some point it became really confusing as to where the ‘props’ were coming from and it was easy to break things if you moved a component in between the data and the component using the data.
In this case Redux greatly simplified the app. So in general if Redux make the app more complex, I would just roll without it. You can go pretty far with setState and passing that state object down to children.
Also worth noting if you want to use Redux 100% like ‘normal’ apps then you can use Meteor methods instead of AJAX to use the same pattern. This is also very useful for scaling issues or when you don’t need realtime data… remember just because you can subscribe to a realtime feed doesn’t mean you should. A lot of data can be just fetched one time. Redux make this super simple.
basically anywhere except for reducers, as they have to be pure functions (ajax calls will produce side effects). However, the action creator function is a great place for side effects.
You could get more complicated and could use fancy middlewares to do these requests and reduce boilerplate but I like to keep it simple and readable.
Example:
export function updatePost(data) {
// make side effects here and not in the view
analytics.track('update post', data.id)
// call API or call meteor method
API.Posts.create(data, (err, res) => {
dispatch({
type: 'UPDATE_POST_LOADED',
loading: false,
payload: res.body
})
});
return {
type: 'UPDATE_POST_LOADING',
loading: true
};
}
// somewhere in the UI
dispatch(updatePost({id: 'u123', desc: 'Foo bar'}))
Note this is not doing optimistic loading but you can imagine how that might be done. It first returns an ‘action’ object to let the UI know it should start showing a loading indicator and the ajax call will eventually dispatch another ‘action’ object which the reducer picks up and inserts into the store.
@SkinnyGeek, I’ve picked out all the terms I do not understand or know from your last post: reducers, pure functions, ajax calls (kinda know about), side effects, action creator, fancy middlewares (kinda know about), optimistic loading, ‘action’ object, store.
Things use to be so simple with Meteor, I understood all the terminology and knew how to accomplish almost everything I needed, I could follow along with every thread, but now I feel like I’m back to square one.
Tell me why we need yet another tech, Redux with React, inside of Meteor again?
@aadams We don’t need it. Redux is just a better way to organise your UI state/logic. It’s optional. Some of the terms relate to functional programming (pure functions, side effects), and some to Redux (reducers, action creators, middleware, stores, actions).
Redux is better at organising than what exactly (inside Meteor)? Why is it better? Why do we need to change data flow techniques and tech because we’re switching out Blaze for React?
I think SkinnyGeek1010 wrote in one of his posts the he thinks Redux is better for managing UI state.
How else can you manage UI state in Meteor apps:
Save values in Session or ReactiveDict
Save values in ReactiveVars that are owned by UI Components (Blaze template, React component etc.)
Save all the UI state to MongoDB documents
So in order to write a Meteor app you don’t need to know Redux, but learning and knowing about different ways of doing things and the pros and cons helps you to make better decisions for your app architecture if you are in a position where you can influence those decisions.
@sanjo, that sounds reasonable and logical. Yet, the tools Meteor has provided for managing state have worked great for me so far, how much “extra” do we actually get from using a Redux “store”?
Is it all about organization as some have implied? Do we only use Redux in place of Session and ReactiveDict? And I keep hearing about Relay, is that going to wipe out Redux or are they complementary?
These seem like good questions. If you have an insanely complex dashboard UI with lots of client-side only stated components with dependencies, maybe the overhead abstraction of Redux makes sense?
If you’re (a mostly single client) viewing/modifying data in a DB then perhaps it doesn’t add that much? I personally prefer the minimongo API rather than having to declare the various dispatch actions and binding to stores etc…
Every problem in computer science adds another layer of abstraction. Now you have two more problems or… more turtles below.
If it’s comparing to an AJAX way of doing things it’s a different discussion.