I have tried it in production mode and it runs well on localhost. but when I tried it on my web hosting there was an error like this:

Could not find "store" in the context of "Connect(ConnectedRouterWithContext)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(ConnectedRouterWithContext) in connect options.

Why did it happen ? even when I check the store is already exists :

{dispatch: ƒ, subscribe: ƒ, getState: ƒ, replaceReducer: ƒ, liftedStore: {…}, …}
dispatch: ƒ (action)
getState: ƒ f()
liftedStore: {dispatch: ƒ, subscribe: ƒ, getState: ƒ, replaceReducer: ƒ, Symbol(observable): ƒ}
replaceReducer: ƒ (n)
subscribe: ƒ subscribe(listener)
Symbol(observable): ƒ ()
__proto__: Object

I took an example from this repository and changed it: https://github.com/cereallarceny/cra-ssr.git

I wonder why on localhost it can work but not on web hosting ?

Here is my code :

I tried to make a react server side rendering.

store.js

import { createStore, applyMiddleware, compose } from "redux";
import { connectRouter, routerMiddleware } from "connected-react-router";
import thunk from "redux-thunk";
import { createBrowserHistory, createMemoryHistory } from "history";
import rootReducer from "./reducers";
import { googleAnalytics } from './reactGAMiddlewares'
import createRootReducer from './reducers'

// import {composeWithDevTools} from 'redux-devtools-extension';
// A nice helper to tell us if we're on the server
export const isServer = !(
  typeof window !== "undefined" &&
  window.document &&
  window.document.createElement
);

export default (url = "/") => {
  // Create a history depending on the environment
  const history = isServer
    ? createMemoryHistory({
        initialEntries: [url]
      })
    : createBrowserHistory();

  const enhancers = [];

  // Dev tools are helpful
  if (process.env.NODE_ENV === "development" && !isServer) {
    const devToolsExtension = window.__REDUX_DEVTOOLS_EXTENSION__;

    if (typeof devToolsExtension === "function") {
      enhancers.push(devToolsExtension());
    }
  }

  const middleware = [thunk, routerMiddleware(history)];
  const composedEnhancers = compose(
    applyMiddleware(...middleware),
    applyMiddleware(googleAnalytics),
    ...enhancers
  );
  // const composedEnhancers = composeWithDevTools(
  //   applyMiddleware(...middleware)
  // );

  // Do we have preloaded state available? Great, save it.
  const initialState = !isServer ? window.__PRELOADED_STATE__ : {};

  // Delete it once we have it stored in a variable
  if (!isServer) {
    delete window.__PRELOADED_STATE__;
  }

  // Create the store
  const store = createStore(
    createRootReducer(history),
    // connectRouter(history)(rootReducer),
    initialState,
    composedEnhancers
  );

  return {
    store,
    history
  };
};

Index.js

import React from "react";
import { render, hydrate } from "react-dom";
import { Provider } from "react-redux";
import Loadable from "react-loadable";
import { Frontload } from "react-frontload";
import { ConnectedRouter } from "connected-react-router";
import createStore from "./store";
import App from "./app/app";
import { BrowserRouter as Router} from 'react-router-dom';
const { store, history } = createStore();

// Running locally, we should run on a <ConnectedRouter /> rather than on a <StaticRouter /> like on the server
// Let's also let React Frontload explicitly know we're not rendering on the server here
const Application = (
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Frontload noServerRender={true}>
        <App />
      </Frontload>
    </ConnectedRouter>
  </Provider>
);

const root = document.querySelector("#root");

if (root.hasChildNodes() === true) {
  // If it's an SSR, we use hydrate to get fast page loads by just
  // attaching event listeners after the initial render
  Loadable.preloadReady().then(() => {
    hydrate(Application, root);
  });
} else {
  // If we're not running on the server, just render like normal
  render(Application, root);
}

Reducer.js

export default (history) => combineReducers({
    router: connectRouter(history),
    products: productReducer,
    carts: cartReducer,
});

App.js

// The basics
import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import { withRouter } from "react-router";
// Action creators and helpers
// import { establishCurrentUser } from '../modules/auth';
import { isServer } from "../store";
import Routes from "./routes";
import Loadable from "react-loadable";

const MainLayout = Loadable({
  loader: () =>
    import(/* webpackChunkName: "dashboard" */ "./components/layouts/MainLayout"),
  loading: () => null,
  modules: ["MainLayout"]
});
class App extends Component {
  render() {

    return ( 
          <MainLayout>
              <ScrollToTop>
                <Routes />
              </ScrollToTop>
          </MainLayout>
    );
  }
}

export default withRouter(App);

0 Answers