Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Container Component cannot find Store

I'm running into this error: Invariant Violation: Could not find "store" in either the context or props of "Connect(Filters)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Filters)".

The root of the app looks like so:

import { AppContainer } from 'react-hot-loader';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import Root from './Root';
import configureStore from './store/configure-store';

const props = Object.assign({}, JSON.parse(document.getElementById('initial-json').innerHTML));
const reduxProps = { filters: props.filters };
const store = configureStore(reduxProps);

render(
  <Provider store={store}>
    <AppContainer>
      <Root {...props} />
    </AppContainer>
  </Provider>,
  reactRoot
);

Root Component

export default Root extends Component {

  render() {
    return(
      <div className="someClass">
        <Filters />
        <Body />
      </div>
    )
  }
}

And Filters is being hooked into Redux like so:

Filters

class Filters extends Component {} ...

const mapStateToProps = (props) => {
  return props;
};

export default connect(mapStateToProps)(Filters);
// have also tried: connect()(Filters);

At first, I thought this might be just an error in how the component was being connected to the Redux store, however I've tried this on a few different components nested inside of Root including Root itself. I have also tried wrapping only Filters in the Provider but this introduces the problem where RHL reloads the store.

Finally, I'm beginning to suspect this has something to do with the way the store is being configured. So I'm looking through configure-store:

configure-store.js

import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
import logger from 'redux-logger';
import rootReducer from '../reducers';
import rootSaga from '../sagas';

const sagaMiddleware = createSagaMiddleware();
const enhancer = compose(applyMiddleware(sagaMiddleware, logger));

export default function configureStore(initialState) {
  const store = createStore(rootReducer, initialState, enhancer);
  sagaMiddleware.run(rootSaga);

  if (module.hot) {
    /* eslint-disable */
    module.hot.accept('../reducers', () =>
      store.replaceReducer(require('../reducers').default)
    );
  }

  return store;
}

My question thus far: Is there something amiss with the way I'm configuring the store, or is there something else I'm not seeing here? Thank you.

EDIT:

The redux store should be accessible from the root component via this.context.store. When logged from the root component, this.context returns an empty object...

Screenshot of store prior to being passed to the Provider.

enter image description here

like image 896
Jose Avatar asked Apr 03 '18 21:04

Jose


2 Answers

Why are you invoking render with the jsx passed to it? Within a React component we should define our render method. Something like

render() {
    return (
        <div className="someClass">
            <Filters />
            <Body />
        </div>
    )
}

This allows us to make use of the components this.props and this.state and derive how we generate content based on those values.

Be careful not to get confused with reactDom.render.

like image 197
Thomas Avatar answered Sep 29 '22 09:09

Thomas


This ended up being something strange. I downgraded the react, react-dom and react-redux packages to several versions prior and got rid of the error entirely. After upgrading the packages to the latest versions to reproduce the bug, I am unable to.

like image 30
Jose Avatar answered Sep 29 '22 09:09

Jose