reactjsreact-routerreact-reduxreact-router-reduxreact-router-v4

React Router work on reload, but not when clicking on a link


I have setup the React with react-router version 4. The routing works when I enter the URL directly on the browser, however when I click on the link, the URL changes on the browser (e.g http://localhost:8080/categories), but the content don't get updated (But if I do a refresh, it gets updated).

Below is my setup:

The Routes.js setup as follows:

import { Switch, Route } from 'react-router-dom';
import React from 'react';

// Components
import Categories from './containers/videos/Categories';
import Videos from './containers/videos/Videos';
import Home from './components/Home';

const routes = () => (
  <Switch>
    <Route exact path="/" component={Home}/>
    <Route path="/videos" component={Videos}/>
    <Route path="/categories" component={Categories}/>
  </Switch>
);

export default routes;

The link I use in Nav.js are as follows:

<Link to="/videos">Videos</Link>
<Link to="/categories">Categories</Link>

The App.js is as follows:

import React from 'react';
import './app.scss';
import Routes from './../routes';
import Nav from './Nav';

class AppComponent extends React.Component {

  render() {
    return (
      <div className="index">
        <Nav />
        <div className="container">
          <Routes />
        </div>
      </div>
    );
  }
}

AppComponent.defaultProps = {
};

export default AppComponent;

Solution

  • Wrapping your component with withRouter should do the job for you. withRouter is needed for a Component that uses Link or any other Router props and doesn't receive the Router props either directly from Route or from the Parent Component

    Router Props are available to the component when its called like

    <Route component={App}/>
    

    or

    <Route render={(props) => <App {...props}/>}/>
    

    or if you are placing the Links as direct children of Router tag like

    <Router>
         <Link path="/">Home</Link>
    </Router>
    

    In case when you wish to write the child content within Router as a component, like

    <Router>
         <App/>
    </Router>
    

    The Router props won't be available to App and hence, you could pass call it using a Route like

    <Router>
         <Route component={App}/>
    </Router>
    

    However withRouter comes in Handy when you want to provide the Router props to a highly nested component. Check this solution

    import {withRouter} from 'react-router'
    
    class AppComponent extends React.Component {
    
      render() {
        return (
          <div className="index">
            <Nav />
            <div className="container">
              <Routes />
            </div>
          </div>
        );
      }
    }
    
    AppComponent.defaultProps = {
    };
    
    export default withRouter(AppComponent);