React-router,Redux,服务器端渲染:不断违反:浏览器历史记录需要DOM

时间:2018-07-05 04:11:23

标签: javascript reactjs redux react-router serverside-rendering

我是服务器端渲染的新手。我的堆栈主要是:Webpack,React,React-Router,Redux,Babel。捆绑软件的创建效果很好。但是,当我打开浏览器时,出现此错误:

  

永久违反:浏览器历史记录需要DOM

我不知道出什么问题了。

这是我的server.js:

// create htmlTemplate to serve to client
const htmlTemplate = (template, initialState) => { 
  `<!DOCTYPE html>
   <head>
     <title>Universal Reacl</title>
     <link rel="stylesheet" href="./css/main.css">
   </head>
   <body><div id="root">${template}</div>
   <script>window.__INITIAL_STATE__=${JSON.stringify(initialState)}</script>
   <script src="./bundle.js" defer></script>

   </body>
 </html>
 `
}

// listen client request => release server file 
app.use((req,res) => { 



    // create store with appReducer inside
    const store=configureStore();

  const branch = matchRoutes(routes, req.url);
  const promises = branch.map(({route}) => {
    let fetchData = route.component.fetchData;
    return fetchData instanceof Function ? fetchData(store) : Promise.resolve(null)
  });
  return Promise.all(promises).then((data) => {
    let context = {};
    const template = renderToString(
      <Provider store={store}>
        <StaticRouter location={req.url} context={context}>
          {renderRoutes(routes)}
        </StaticRouter>
      </Provider>
    );
   if(context.status === 404) {
          res.status(404);
   }


            // set initial component _ state 
            const initialState=store.getState() 

            // set html server's page 
            const HTML=htmlTemplate(template, initialState);

            res.end(HTML);
        });
})

export default app;

这是我的client.js:

// view 
import React from 'react';
import {hydrate} from "react-dom" ;

// router 
import { BrowserRouter } from 'react-router-dom'
import createBrowserHistory from 'history/createBrowserHistory'
import  {AppRoute}  from "../app/Router";

// data flow
import {configureStore} from "../app/store";
import {Provider} from 'react-redux';

const history = createMemoryHistory();

let initialState=window.__INITIAL_STATE__; 

const store = configureStore(initialState); 

const root=document.getElementById('root')


hydrate(
    <Provider store={store}>    
    {() =>
    <BrowserRouter history={history}>
    <AppRoute/>
    </BrowserRouter>
    }
    </Provider>,
    root
)

在我看来,一切都很棒,可以获取数据,推送路由,而且如果有人暗示发生了什么事情,那一切都会很棒,

谢谢

0 个答案:

没有答案