Я пробовал его в производственном режиме, и он хорошо работает на локальном хосте. но когда я попробовал это на моем веб-хостинге, была ошибка как это:
Не удалось найти "store" в контексте
"Connect (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);