javascript - How to implement a universal router with react-router v2 -


react-redux-universal-hot-example once had universal router, see universalrouter, client.js, server.js. i'd create improved version of can render error page if api action returned error. use react-router 2 unlike used in rruhe.

my problem when press link, transition never occurs , listenbefore never called on client.

some parts of code:

universalrouter.js:

import react                  'react'; import {   match,   routercontext,   router }                             'react-router'; import { provider }           'react-redux';  import fetchcomponentdata './fetchcomponentdata';  export default function universalrouter(routes, location, store) {   return new promise((resolve, reject) => {     rematch(routes, location, store, resolve, reject);   }); }  function rematch(routes, location, store, resolve, reject, rematched = false) {   match({routes, location}, (error, redirectlocation, renderprops) => {     if (error) {       return reject(error);     }      if (redirectlocation) {       return resolve({         redirectlocation       });     }      fetchcomponentdata(store, renderprops.components, renderprops.params)       .then(resolvewithcomponent, (error) => {         if (!rematched && error.status) {           rematch(routes, geterrorpagepath(error), store, resolve, reject, true);         } else {           reject(error);         }       });      function resolvewithcomponent() {       const component = (         <provider store={store}>           <routercontext {...renderprops}/>         </provider>       );       resolve({component, matchedroutes: renderprops.routes})     }   }); }  // todo implement geterrorpagepath, return '/404' function geterrorpagepath(error) {   return '/404'; } 

client.js:

... const renderapp = (location) => {   return universalrouter(routes, location, store)     .then(({component}) => {       render(component, document.getelementbyid('react-view'));     }, (error) => {       // todo print error in dev mode.       console.error(error);     }); };  history.listenbefore((location, callback) => {   console.log('this message never printed console');   renderapp(location)     .then(callback); });  renderapp(pathname + search); 

server.js:

... universalrouter(routes, req.url, store)     .then(({component, matchedroutes}) => {       const componenthtml = rendertostring(component);       const initialstate = store.getstate();       const html = `       <!doctype html>       <html>         <head>           <meta charset="utf-8">           <link rel="shortcut icon" href="/favicon.ico">           <title>redux demo</title>           <script>             window.__initial_state__ = ${json.stringify(initialstate)};           </script>         </head>         <body>           <div id="react-view">${componenthtml}</div>           <script type="application/javascript" src="/dist/bundle.js"></script>         </body>       </html>       `;       res.status(getstatus(matchedroutes)).send(html);     }, (error) => {       res.sendstatus(500);       console.error(error)     });  function getstatus(routes) {   return routes.reduce((prev, curr) => curr.status || prev) || 200; } 

fixed providing history object match:

client.js:

  return universalrouter(routes, location, store, history) 

universalrouter.js:

... export default function universalrouter(routes, location, store, history) {   return new promise((resolve, reject) => {     rematch(routes, location, store, history, resolve, reject);   }); }  function rematch(routes, location, store, history, resolve, reject, rematched = false) {   match({routes, location, history}, (error, redirectlocation, renderprops) => { ... 

if someone's interested in universal router, take @ this gist , this comment on github..


Comments