I'm relatively new to SSR with React and Redux, so I assume I'm making a simple mistake that reflects my lack of understanding of the underlying frameworks. However, I'm about to put my head through a wall, so here goes. Hope someone can help.
If I try to navigate directly to the root page (/), I get the error Could not find "store" in the context of "Connect(Home)"
. In my case, App
contains my shared navigation logic and global content, and (/) renders a Home
component. If I navigate to a page that does NOT connect to Redux (e.g. Terms of Service), and THEN navigate to my home page, it renders perfectly. I assume this is some kind of server-side routing issue, but I've read everything I can find online, tried what feels like every possible permutation of state / store / context handling, and I can't resolve it.
Here is the skeleton of my code.
renderer.js
[...]
const modules = [];
const routerContext = {};
const bundle = (
<Loadable.Capture report={m => modules.push(m)}>
<ReduxProvider store={store}>
<StaticRouter location={req.baseUrl} context={routerContext}>
<CookiesProvider cookies={req.universalCookies}>
<App />
</CookiesProvider>
</StaticRouter>
</ReduxProvider>
</Loadable.Capture>
);
const html = ReactDOMServer.renderToString(bundle);
if (routerContext.url) {
redirect(301, routerContext.url);
}
// inject into HTML
[...]
configureStore.js
[...]
const createStoreWithMiddleware = compose(applyMiddleware(ReduxThunk))(createStore);
export default function configureStore(initialState = {}) {
return createStoreWithMiddleware(rootReducer, initialState);
};
index.js (client)
const store = configureStore( window.__REDUX_STATE__ || {} );
const AppBundle = (
<ReduxProvider store={store}>
<BrowserRouter>
<CookiesProvider>
<App />
</CookiesProvider>
</BrowserRouter>
</ReduxProvider>
);
window.onload = () => {
Loadable.preloadReady().then(() => {
ReactDOM.hydrate(
AppBundle,
document.getElementById('root')
);
});
};
app.js ("/" renders the Home component)
[...]
export default withCookies(App);
[...]
home.js
[...]
export default connect(mapStateToProps)(Home);
[...]