Nadeem Ahmad
Nadeem Ahmad

Reputation: 745

"Link" is not navigating to the specified routes - React JS (react-route-dom)

I am working with React JS routes and installed react-route-dom. I have two main components, side-bar.js and nav.js. side-bar.js has some components like discussion.js, friends.js etc that should be loaded according to the provided URL/specified path.

I have specified the routes in the side-bar.js and <Links to="/path" /> in the nav.js. When I click the link on nav.js it changes the specified path (the URL is changed) but the route is still the same (the same component is shown), as it should switch between the discussion.js, friends.js etc. But on the other hand, when I refresh the page with the specified paths in the <Link to="/discussion"/>, the required component is loaded accordingly. I don't know what the problem is that it only works on page refresh and not with link.

side-bar.js code

import React, { Component } from 'react'
import Discussion from './side-bar-components/discussion'
import Friends from './side-bar-components/friends'
import Notifications from './side-bar-components/notifications'
import Settings from './side-bar-components/settings'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';


export class sidebar extends Component {

    constructor(props) {
        super(props)
    
        this.state = {
             
        }
    }
    
    render() {
        return (
            <div className="sidebar">
                <div className="container">
                    <div className="tab-content">
                        <Router>
                            <Switch>
                                <Route path={'/'} exact component={Discussion}/>
                                <Route path={'/discussion'} component={Discussion}/>
                                <Route path={'/friends'}  component={Friends}/>
                                <Route path={'/notifications'}  component={Notifications}/>
                                <Route path={'/settings'}  component={Settings}/>
                            </Switch>
                        </Router>

                    </div>
                </div>
            </div>
        )
    }
}

export default sidebar

nav.js code

import React, { Component } from 'react'
import {Link, BrowserRouter} from 'react-router-dom';

export class nav extends Component {
    render() {
        return (
                <nav className="navigation">
                    <div className="container">
                        <a href="#nav" className="logo" rel="home"> <img src="dist/img/logo.png" alt="logo" /> </a>
                        <ul className="nav" role="tablist">
                            <BrowserRouter>
                                <li>
                                    <Link to="/discussion">
                                        <i data-eva="message-square" data-eva-animation="pulse"></i>
                                    </Link>
                                </li>
                                <li>
                                    <Link to="/friends">
                                        <i data-eva="people" data-eva-animation="pulse"></i>
                                    </Link>
                                </li>
                                <li>
                                    <Link to="/notifications">
                                        <i data-eva="bell" data-eva-animation="pulse"></i>
                                    </Link>
                                </li>
                                <li>
                                    <Link to="/settings">
                                        <i data-eva="settings" data-eva-animation="pulse"></i>
                                    </Link>
                                </li>
                                <li><button type="button" className="btn mode"><i data-eva="bulb" data-eva-animation="pulse"></i></button></li>
                                <li><button type="button" className="btn"><img src="dist/img/avatars/avatar-male-1.jpg" alt="avatar" /><i data-eva="radio-button-on"></i></button></li>
                            </BrowserRouter>
                        </ul>
                    </div>
                </nav>
        )
    }
}

export default nav

home.js code (Parent Component)

import React, { Component } from 'react';
import Nav from './app-components/nav'
import Sidebar from './app-components/sidebar'
import Compose from './app-components/compose'
import Chat from './app-components/chat'


export class home extends Component {

    constructor(props) {
        super(props)
    
        this.state = {
             
        }
    }


    

    render() {
        return (
            <div className="layout">

                <Nav />
                <Sidebar />
                <Chat />
                <Compose />
            
            </div>
        )
    }
}

export default home

Upvotes: 0

Views: 1533

Answers (1)

Asaf Aviv
Asaf Aviv

Reputation: 11760

You will need to remove BrowserRouter from nav and handle the routes from the parent component.

Include the components you want to always show inside Router but outside of Switch and the components you want to act as pages inside Route

import React, { Component } from "react";
import ReactDOM from "react-dom";
import {
  Link,
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";
import "./styles.css";

const renderLink = path => <Link to={`/${path}`}>{path}</Link>;

const NestedDiscussion = ({ match }) => (
  <div>
    <h1>nested route for discussion {match.params.id}</h1>
  </div>
);

const Discussion = ({ match }) => (
  <div>
    <h1>discussion</h1>
    <Link to={`${match.url}/1`}>Discussion 1</Link>
    <Link to={`${match.url}/2`}>Discussion 2</Link>
    <Link to={`${match.url}/3`}>Discussion 3</Link>
    <Route path={`${match.url}/:id`} component={NestedDiscussion} />
  </div>
);

const Friends = () => <h3>Friends</h3>;
const Notifications = () => <h3>Notifications</h3>;
const Settings = () => <h3>Settings</h3>;

class SideBar extends Component {
  render() {
    return (
      <div className="sidebar">
        <div className="container">
          <div className="tab-content">SideBar</div>
        </div>
      </div>
    );
  }
}

class Nav extends Component {
  render() {
    return (
      <nav className="navigation">
        <div className="container">
          <ul className="nav" role="tablist">
            {renderLink("discussion")}
            {renderLink("friends")}
            {renderLink("notifications")}
            {renderLink("settings")}
          </ul>
        </div>
      </nav>
    );
  }
}

function App() {
  return (
    <div className="App">
      <Router>
        <Nav />
        <SideBar />
        <Switch>
          <Route
            path={"/"}
            exact
            render={() => <Redirect to="/discussion" />}
          />
          <Route path={"/discussion"} component={Discussion} />
          <Route path={"/discussion/:id"} component={Discussion} />
          <Route path={"/friends"} component={Friends} />
          <Route path={"/notifications"} component={Notifications} />
          <Route path={"/settings"} component={Settings} />
        </Switch>
      </Router>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

sandbox

Upvotes: 1

Related Questions