浏览器历史记录需要一个DOM(React-Router 4)



我正在尝试在我的React应用中实现服务器端渲染。我无法使用React,React-Dom和React-Router的服务器实现访问DOM。我要么有"浏览器历史记录"错误。

所以我的猜测是我在服务器或客户端包装组件的方式中有问题。

我将分享我的结构和涉及的重要文件!

server.js

import React from 'react';
import { renderToString } from 'react-dom/server';
// import { StaticRouter } from 'react-router';
import {StaticRouter} from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { ConnectedRouter, routerMiddleware } from 'react-router-
redux';
import { multiClientMiddleware } from 'redux-axios-middleware';
import api from "../src/actions/api";
import rootReducer from "../src/reducers/index";
import routes from '../src/routes/routes';
const app = express();
app.use(express.static('public'));
app.get('*', (req,res)=>{
const axiosMiddlewareOptions = {
    interceptors: {
        request: [
            (action, config) => {
                if (sessionStorage.token) {
                    config.headers['Authorization'] = 'Token '+ sessionStorage.token;
                }
                return config
            }
        ]
    }
};
const history = createBrowserHistory();
const appRouterMiddleware = routerMiddleware(history);
const createStoreWithMiddleware = 
applyMiddleware(multiClientMiddleware(api, axiosMiddlewareOptions), 
appRouterMiddleware)(createStore);
const store = createStoreWithMiddleware(rootReducer, {}, 
window.devToolsExtension ? window.devToolsExtension() : f => f);
const context = {};
const html = renderToString(
    <Provider store={store}>
        <StaticRouter location={req.url} context={context}>
            <ConnectedRouter history={history} children={routes}/>
        </StaticRouter>
    </Provider>
);
res.send(`
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
            <base href="/"/>
            <link href="assets/img/favikin-hw.png" rel="shortcut 
 icon" type="image/x-icon" />
            <meta name="viewport" content=" width=device-width, 
 maximum-scale=1">
        </head>
        <body>
            <div class="wrapper">${html}</div>
        </body>
    </html>
`)
});
app.listen(process.env.PORT || 8080, ()=>{
   console.log('Server is Listening')
});

index.js

import React from 'react';
import { render } from 'react-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { ConnectedRouter, routerMiddleware } from 'react-router-redux';
import { multiClientMiddleware } from 'redux-axios-middleware';
import api from "./actions/api";
import rootReducer from "./reducers/index";
import routes from './routes/routes';
import { BrowserRouter } from 'react-router-dom';
import '../assets/css/bootstrap.min.css';
import '../assets/style.css';
import '../node_modules/react-datetime/css/react-datetime.css';
import '../node_modules/react-select/dist/react-select.min.css';
const axiosMiddlewareOptions = {
    interceptors: {
    request: [
        (action, config) => {
            if (sessionStorage.token) {
                config.headers['Authorization'] = 'Token '+     sessionStorage.token;
            }
            return config
        }
    ]
    }
};
const history = createBrowserHistory();
const appRouterMiddleware = routerMiddleware(history);
const createStoreWithMiddleware =     applyMiddleware(multiClientMiddleware(api, axiosMiddlewareOptions),     appRouterMiddleware)(createStore);
const store = createStoreWithMiddleware(rootReducer, {},     window.devToolsExtension ? window.devToolsExtension() : f => f);
render(
    <Provider store={store}>
        <ConnectedRouter history={history} children={routes}/>
    </Provider>,
document.querySelector('.wrapper'));

app.js

import React, { Component, PropTypes } from "react";
import Header from '../components/Header/Header';
import Footer from '../components/Footer/Footer';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
class App extends Component {
    render() {
        return (
        <MuiThemeProvider>
            <div className="wrapper-box">
                <div className="inner-wrapper">
                    <Header/>
                    {this.props.children}
                </div>
                <Footer/>
            </div>
        </MuiThemeProvider>
    );
    }
}
App.propTypes = {
    children: PropTypes.object.isRequired
};
export default App;

routes.js

import React from 'react';
import App from '../containers/App';
import {
    Route,
    Switch
} from 'react-router-dom';
import MainPage from '../containers/MainPage/MainPage';
import DetailPage from '../components/DetailPage/DetailPage';
import AboutProject from '../containers/AboutProject/AboutProject';
import Contacts from '../containers/Contacts/Contacts';
import SectionPage from '../containers/SectionPage/SectionPage';
import SearchPage from '../containers/SearchPage/SearchPage';
import NoMatch from '../containers/NoMatch/NoMatch';

export default (
<App>
    <div>
        <Switch>
            <Route exact={true} path='/' component={MainPage} />
            <Route path='/about_the_project' component={AboutProject} />
            <Route path='/contacts' component={Contacts} />
            <Route path="/search-results/:category/:term" component={SearchPage}/>
            <Route exact={true} path='/:name' component={SectionPage} />
            <Route path="/articles/:slug" component={DetailPage}/>
            <Route path="/events/:slug" component={DetailPage}/>
            <Route path="/news/:slug" component={DetailPage}/>
            <Route path="/interviews/:slug" component={DetailPage}/>
            <Route path="/technologies/:slug" component={DetailPage}/>
            <Route path='*' component={NoMatch}/>
        </Switch>
    </div>
    </App>
)

通过使用createMoryhistory((

解决了错误

const历史= createMoryhistory((;

我还没有时间对其进行测试,但是ConnectRouter具有一个称为ISSSR的道具,可以防止订阅仅限的东西。(https://github.com/reacttraining/react-router/blob/master/packages/react-router-redux/modux/modules/connectedrouter.js(

我的猜测是您现在可以使用memoryHistory。(https://github.com/reacttraining/react-router/blob/master/packages/react-router/docs/api/history.md(

将尝试在周末获得一个示例应用程序。

最新更新