React router doesn't load page from other component page

Viewed 169

I am using react with django in backend. When the link is clicked from component page I want the respective page to open. But page doesn't render anything.

This is my homepage.js where main react router is defined.

 <Router>
        <Navigation />
        <Switch>
            <Route exact path= "/">
                <Home />
            </Route>
            <Route path="/communication">
                <Communication />
            </Route>
            {/* <Route path="/forum-create" component={ForumCreate} /> */}
            <Route path="/calendar">
                <EventCalendar />
            </Route>
            <Route path="/information">
                <Informations />
            </Route>
            <Route path="/links">
                <Links />
            </Route>
        </Switch>
    </Router>

I have defined the Route in another from which I want to render page.

import React from 'react'
import {BrowserRouter as Router, Switch, Route, Link, Redirect,} from 'react-router-dom'


function Communication() {
    return (
        <div>
            <Forum />
            {/* <Route path="/forum-create" component={ForumCreate} /> */}

        </div>
    )
}


function Forum() {
    return (
        <div>
            <h2 className="page-head">Forum</h2>
            <div className="forum">
                <Link to="forum-create">Create Topic</Link>
                <table className="forum-table">
                    <th>
                        <td>Topic</td>
                    </th>
                    <th>
                        <td>Date</td>
                    </th>
                    <th>
                        <td>Posted By</td>
                    </th>
                    <tr>
                        <td>Test Topic</td>
                        <td>20/05/2021</td>
                        <td>Awesome User</td>
                    </tr>
                    <tr>
                        <td>Test Topic</td>
                        <td>20/05/2021</td>
                        <td>Awesome User</td>
                    </tr>
                </table>
            </div>
        </div>
    )
}


function ForumCreate() {
    return (
        <div>
            Create a Topic Forum
            Some Chagnes
        </div>
    )
}

export default Communication

I want to render component ForumCreate() from communication page only. I have tried putting path in homepage.js inside Route but still clicking on Link doesn't load up the ForumCreate function. I can render this function if its in homepage.js

1 Answers

When Communication component is being rendered the current path is path="/communication", so if you now render additional routes that have a different path prefix (i.e. something other than "/communication") like path="/forum-create", then when you link to that route the Switch no longer matches "/communication" and the Communication component unmounts, thus unmounting the <Route path="/forum-create" component={ForumCreate} /> route component.

The solution is to either declare the forum create route out at the root level with the Switch so it's always available to be matched and rendered, or nested as a sub-route of "/communication".

As a root level route.

<Router>
  <Navigation />
  <Switch>
    <Route exact path= "/">
      <Home />
    </Route>
    <Route path="/communication">
      <Communication />
    </Route>
    <Route path="/forum-create" component={ForumCreate} /> // <-- render in root
    <Route path="/calendar">
      <EventCalendar />
    </Route>
    <Route path="/information">
      <Informations />
    </Route>
    <Route path="/links">
      <Links />
    </Route>
  </Switch>
</Router>

Render as a nested route.

function Communication() {
  return (
    <div>
        <Forum />
        <Route
          path="/communication/forum-create" // <-- nested route
          component={ForumCreate}
        />
    </div>
  )
}

function Forum() {
  return (
    <div>
      <h2 className="page-head">Forum</h2>
      <div className="forum">
        <Link to="/communication/forum-create"> // <-- nested route
          Create Topic
        </Link>
        ...
      </div>
    </div>
  )
}
Related