Search code examples
javascriptreactjsreact-routerjsxreact-dom

How to upgrade from react-router to react-router-dom?


If i want to upgrade from "react-router": "^2.0.0" to "react-router": "^4.0.0","react-router-dom": "^4.0.0". My structure should be like this:

  1. Main Component :is a container component for every thing (the parent).
  2. Nav Component :is used to navigate among my other child components and this component should appear always.
  3. Child Components: Examples , About ,Test. where Test is the Default.

My old code which works as expected is like this :

-App.jsx

var {Route, Router, IndexRoute, hashHistory} = require('react-router');

        ReactDOM.render(
          <Router history={hashHistory}>
            <Route path="/" component={Main}>
              <Route path="about" component={About}/>
              <Route path="examples" component={Examples}/>
              <IndexRoute component={Test}/>
            </Route>
          </Router>,
          document.getElementById('app')
        );

-Main Component is like this :

var React = require('react');
var Nav = require('Nav');

var Main = (props) => {
  return (
    <div>
      <Nav/>
      {props.children}
    </div>
  );
}

module.exports = Main;

-My Nav Component is like this :

var React = require('react');
var {Link, IndexLink} = require('react-router');

var Nav = () => {
  return (
    <div>
      <IndexLink to="/" activeClassName="active" activeStyle={{fontWeight: 'bold'}}>Test</IndexLink>
      <Link to="/about" activeClassName="active"  activeStyle={{fontWeight: 'bold'}}>About</Link>
      <Link to="/examples" activeClassName="active" activeStyle={{fontWeight: 'bold'}}>Examples</Link>
    </div>
  );
};

module.exports = Nav;

I try to upgrade like this:

-App.jsx

var { BrowserRouter, Route } =require('react-router-dom');

ReactDOM.render(
  <BrowserRouter>
   <div>
       <Route path='/' component={Main} />
       <Route path='/Test' component={Test}/>
       <Route path='/about' component={About}/>
       <Route path='/examples' component={Examples}/>
   </div>
  </BrowserRouter>,
  document.getElementById('app')
);

-My Main Component has no changes

-My Nav Component is like this :

var React = require('react');
var {Link, NavLink} =require('react-router-dom');
var Nav = ()=>{
  return(
    <div>
    <NavLink activeClassName="active" activeStyle={{fontWeight: 'Bold'}} to="/Test">Test</NavLink>
    <NavLink activeClassName="active" activeStyle={{fontWeight: 'Bold'}} to="/about">About</NavLink>
    <NavLink activeClassName="active" activeStyle={{fontWeight: 'Bold'}} to="/examples">Examples</NavLink>
    </div>
  );
}

module.exports = Nav;

I face the following problems :

  • The Test Component isn't the default like before.
  • The Main Component doesn't behave like a parent.
  • When i refresh the browser on Examples, i get the following error :

http://localhost:5000/examples net::ERR_CONNECTION_REFUSED


Solution

  • So you need to change your App.jsx module, so it's rendering only Main component, because now you can move your router in there. React Router v4 is no more rendering it's routes to props children. Now you need to declare it at specific place you want it to be rendered.

    App.jsx

    ReactDOM.render(
          <Main/>,
          document.getElementById('app')
    );
    

    Main component

    var React = require('react');
    var Nav = require('Nav');
    var { HashRouter, Route, Switch } = require('react-router-dom');
    
    var Main = (props) => {
       return (
         <HashRouter>
            <Nav/>
            <Switch>
               <Route path='/about' component={About}/>
               <Route path='/examples' component={Examples}/>
               <Route component={Test}/>
            </Switch>
         </HashRouter>
       );
    }
    
    module.exports = Main;
    
    • So now your Main component can behave like parent.
    • If you remove path attribute for Route component, it will behave like default. Also you might noticed I've added Switch component. It should assure one route is rendered exclusively. You can check detailed info in manual.
    • Before, you had used hashHistory for your Router, now you can do the same using HashRouter. This should resolve error you get.