Search code examples
reactjsparametersroutesblogs

React Router component doesn't render despite matching exact route


I am building a simple blog with React Router, but facing some problems when changing locations.

Expected behaviour:

  1. Route localhost:8080/#/contact should display Contact component contents.

Actual behaviour:

  1. Route localhost:8080/#/contact doesn't render Contact component but only Pagination component navigation links - 1, 2, 3 that is rendered by HomePage component. Please note the comment in code below.

Maybe it has to do with :page parameter in path? Both my 1st and 5th route is using it.

Extra questions:

  1. How to implement pagination on the HomePage so it does not interfere with other routes?
  2. After landing on localhost:8080/#/ HomePage component displays 1st page of blog posts which technically should be on localhost:8080/#/1. Is there a logical workaround that I can use?

my App component:

import {
    HashRouter as Router, Route, Switch, Redirect
} from 'react-router-dom';
const App = () => {
        const routes = (
            <Switch>
                <Route exact path="/" component={HomePage} />
                <Route exact path="/:page?" component={HomePage} /> // commenting this line out causes <Contact /> work properly, but then again pagination on HomePage doesn't work as I don't have parameter in the url.
                <Route exact path="/post/:uid" component={PostPage} />
                <Route exact path="/contact" component={ContactPage} />
                <Route exact path="/category/:category/:page?" component={CategoryPage} />
                <Route component={NotFoundPage} />
            </Switch>
        );
    
        return (
            <>
               <MetaDecorator/>
               <Router>
                 {routes}
               </Router>
            </>
        );
    };

Thank you


Solution

  • Switch always looks through the routes and renders the first route that matches with your routes.

    In this example, you put the /:page route to the top of the Switch. When react router looks for your route, it thinks that, "contact" word in "/contact" is a page id and it should render the /:page route.

    You should put the /:page route before "not found" and try to delete exact keywords from your routes except /.

    return (
      <Switch>
        <Route exact path="/" component={HomePage} />
        <Route path="/post/:uid" component={PostPage} />
        <Route path="/contact" component={ContactPage} />
        <Route path="/category/:category/:page?" component={CategoryPage} />
        <Route path="/:page?" component={HomePage} />
        <Route component={NotFoundPage} />
      </Switch>
    )
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

    Also try to use <BrowserRouter> instead of Router.

    I hope your problem will be fixed.