Use React Router inside Iron Router

I started using React and React Router in an existing project. How can I use React Router with Iron Router?

Here is what I am doing currently:

  • Render a Blaze template using iron router
  • Using Template#onRendered, render React app inside the template.

routes.js

Router.route('/admin/:tab1?/:tab2?/:tab3?/:tab4?', function () {
  this.layout('admin');
});

admin.html

<template name="admin">
  <div id="admin-wrapper"></div>
</template>

admin.js

Template.admin.onRendered(function () {
  render((
    <Router>
      ...
    </Router>
  ), this.find('#admin-wrapper'));
});

But the problem is that the React app does not redraw the components as the URL changes. I have to refresh the whole page in my browser to see an updated page. Any ideas, or alternative approaches?

Unfortunately all DOM based router are using W3C History API pushing their own states on it and making them incompatible. react-router 4 introduces a MemoryRouter you could leverage. By listening to the push and pop state from iron:router on the window.history you could inject a state translation to the MemoryRouter.

2 Likes

Thanks @pierreeric. That was spot on. Solved it by listening to window.history.pushState and pushing the url to memoryHistory used by React Router.

But one thing is unclear: If both Iron Router and React Router are using the same W3C History API, why are they incompatible? After all, there is only one window.history object in the browsing session. Can you share your idea about why?

As mentioned, both routers are pushing different state information that are specific. They rely on these information for their implementation.