Can I not access redux provider/store from within a container/component

Here’s my basic AppRoot starting point (stripped out non-pertinent stuff)

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import { Router, Route, browserHistory } from 'react-router';
import { syncHistoryWithStore, routerReducer } from 'react-router-redux';
import { configureStore } from './stores/configureStore';
const store = configureStore();
const history = syncHistoryWithStore(browserHistory, store);
history.listen(location => {
  console.log('AppRoot history', location);
  // analytics...
});

export let AppRoot = React.createClass({
  render() {
    return (
      <Provider store={store}>
        <Router history={history}>
          <Route path="/campaign/:campaignId" component={ AppContainer } onEnter={ requireUser }>
            <Route path="buckets" component={ CampaignBucketsContainer } />
            <Route path="creatives" component={ CampaignCreativesContainer } />
...

// container layer
export default createContainer((inputs) => {
  ...

// page layer
export default class CampaignBucketsPage extends React.Component {
  constructor(props, context) {
    ...

My problem is that the AppContainer and the CampaignCreativesContainer (et. al.) - neither in the container’s input arguments, nor the page’s constructor do I see the redux store… It’s supposed to be passed down, but somehow I’m missing it… Did meteor loose it for me? Did I mess up? Is there an alternative/better way to get it?

If I can not access it from a container, can I at least access it from the Page included in my container? Example?

If I can not, then what’s the point?

You need to use redux connect, to access the store and dispatch actions.

What you’ll end up with is actually two containers - one for redux, which gives you access to your redux store and dispatches actions to it, and one for your meteor data (what you already have above).

I would suggest reading through this part of the redux docs:
http://redux.js.org/docs/basics/UsageWithReact.html

1 Like

Thanks a lot! I’ve seen the connect() but didn’t understand it, and certainly not the 2 levels of containers.

There’s already a lot of boilerplate and repetition in our code stack, I guess adding more wrapper won’t kill me.


Personal sidenote:

The switch to Meteor 1.3 and React has been a steep learning curve, fun but difficult.
I think it’s a good move, better underlying UI engine, lots of pushing my code forward, better separation of concerns… but still young and unknown… now I’m adding a 2nd layer of container wrappers around it because I’m keeping “state/data” in 2 different places, and I’m considering adding apollo to the mix too…

At some point I wonder if I should either revert back to old school Meteor Blaze or abandon Meteor and jump to a webpack boilerplate for UI and some REST-ful-ish backend (phoenix).

Meteor was amazing for several reasons when I jumped on the bandwagon at 0.5 - it was the only game in town doing what it was doing with realtime data, and it was simple as hell… It is no longer the only game in town (though I still love Meteor the server/client data sync) and while blaze remains unchanged and simple still – the pair of React + Meteor has been harder to adapt to than I expected.

(sorry, tangent over… you guys are awesome, keep being awesome, and thanks for your help!)

3 Likes

Also - do we think there’s a way to make meteor tracker updated / subscribed data to be integrated into Redux?

I could image a process where tracker/subscribed data dispatches an action when data updates locally…

Would this be a good idea (because you only would have 1 level of containers)?

Or would it be a bad idea (because data would be living on the client in 2 places now, and with an extra layer of JS functions to put it into the second place)?

I’m still trying to understand the scope here, but it does seem like Meteor’s containers and Redux are overlapping a fair bit. Please help me reconcile.