我已经在生产模式下尝试了它,并且在localhost上运行良好。但是当我在虚拟主机上尝试使用它时,出现了这样的错误:
在以下情况下找不到“商店” “连接(ConnectedRouterWithContext)”。要么包装根组件 在中,或将自定义React上下文提供程序传递给 和相应的React上下文使用者 连接选项中的Connect(ConnectedRouterWithContext)。
为什么会发生?即使我检查商店是否已经存在:
{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
我从该存储库中举了一个示例,并对其进行了更改:https://github.com/cereallarceny/cra-ssr.git
我想知道为什么在localhost上它可以运行,但不能在虚拟主机上运行吗?
这是我的代码:
我试图做出反应服务器端渲染。
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);