If you’re doing Redux I would try to keep as much state in the store as possible. Sometimes it doesn’t make sense to put it there (like a tab containers active tab perhaps). Being that the timer is so crucial I would definitely put the timer value itself it in the store.
For the actual timer… If you’re thinking about larger scale architecture I would put it in a service object and the have it call an action to increment the store state. then expose start and stop methods. For example:
// client/services/app_timer.js
class AppTimer {
constructor(opts) {
// setup timer and start on init
setInterval(() => {
dispatch(Actions.incrementTimer())
}, opts.interval)
}
start() {
// start back up
}
stop() {
// stop progress
}
}
appTimer = new AppTimer({interval: 100});
// dispatch( Actions.stopTimer() );
However for a smaller app I would do just as you suggested… put it somewhere above the button. It might be good to put it in the same area where the UI is subscribing to the store.
@SkinnyGeek1010 I was wondering, why are you calling Players.update({_id: playerId}, {$inc: {score: 5}}); in the action_creators instead of the reducer?
In Redux, reducers should always be pure. If we make a side effect in the reducer the time-travel dev tools won’t work because it’s harder to replay forward/back.
If we were using async methods we would instead have the action creator dispatch an action on success and fail. I didn’t add error handling for simplicity but you could add that with a callback to update.
Instead of dispatching a new ‘success’ action on a successful update, we’re relying on the flux-helper watcher to watch Players for a change, and then it dispatches a change.
The end result is the same as the async method but more clean. Both would produce side-effects (server call) and both would dispatch a new action when new data arrives, this action handles the new data and adds it to the store.
It’s also worth mentioning you can skip Redux for server state that’s in the database and could just sideload data… but for me keeping all state in Redux makes it more simple to keep data flow in your head and easier to control re-rendering.
Thanks. Good answer! It just seems Redux in Meteor is most useful when working with local state. In the case of Meteor methods the reducers seem to be an unneeded overhead. Of course getting everything in the same flow is nice.
Depends…
For example I often need to show some loading or updating indicator when starting method call and store is nice for that. Than in method callback you deactivate it by another reducer.
Better than waiting for method call result callback directly modifying something what does not even have to exist anymore.
Yea I think for small projects the extra overhead is not worth it (keeping remote state) but in a large project… having all the possible app state in one tree is super nice for react. Each view that needs data just slices off the bit they need with connect() and it shows up as props.
I have a key on this tree for viewer that tracks basically Meteor.user()… all posts are in the app state tree with a key of postsData. The PostsContainer can slice off the postsData array and pass it down as props to the view.
To me this is much easier than using the mixin and potentially having excessive re-rendering problems (I can’t confirm this but it seems to render much more than flux… perhaps due to the lack of batching renders?).
Just to clarify the differences, because some others have thought this, the reducers and meteor methods don’t do the same job. The meteor methods are basically nicer to use ajax calls, both of which can be used in an action creator to determine what to return to a reducer.
Yep. The root of the issue isn’t that the mixin itself if in-efficient… but using it with the subscriptions causes a lot of re-renders (at least in my limited usage). Both the mixin and my flux-helper are using Tracker to re-run. The main differences are flux will batch up multiple renders on the same tick so they run all at once.