MUHAMMAD Siyab
MUHAMMAD Siyab

Reputation: 446

React-router changes location but doesn't render component

I'm using react-router v4 for routing in React. The issues i'm facing is that the react-router changes the location but is unable to render the component. I heard that using redux with react blocks updates but i'm not using redux here .

Sidebar.js

import React, {Component} from 'react';
import {
    BrowserRouter as Router, 
    Link
} from 'react-router-dom';
import $ from 'jquery';
import {withRouter} from 'react-router-dom';

class Sidebar extends Component {
        render () {
            return (
                <Router>
                    <div>
                        <button className="navbar-toggler" data-toggle="collapse" data-target="#pill">
                            <span><i className="fa fa-ellipsis-v"></i> menu</span>
                        </button>
                        <div id="pill">

                            <ul className="nav nav-pills flex-column sidebar">
                                <li className="nav-item">
                                    <Link to="/" className="nav-link">
                                        <i className="fa fa-dashboard"></i> Dashboard 
                                    </Link>
                                </li>
                                <li className="nav-item">
                                    <a href="#students" className="nav-link" data-toggle="collapse">
                                        <i className="fa fa-users"></i> Students 
                                    </a>
                                    <ul className="collapse" id="students" style={{marginLeft: '-25px'}}>
                                        <li className="nav-item"><Link to="/students" className="nav-link"><i className="fa fa-eye"></i> View students</Link></li>
                                    </ul>
                                </li>

                            </ul>
                        </div>
                    </div>

                </Router>
            )
        }

    }

export default withRouter(Sidebar);

App.js

import React, { Component } from 'react';
import Navbar from './Navbar';
import Sidebar from './Sidebar';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import Dashboard from './Dashboard';
import Students from './Students';


class App extends Component {   

    render() {     

        const { match } = this.props;
        return (
            <Router>
        <div>
            <Navbar />
            <div className="container-fluid main">
                <div className="row">
                    <div className="col-sm-2 area-left">
                        <Sidebar />
                    </div>
                    <div className="col-sm-10 area-right float-right">
                        <div>
                            <Route exact path="/" component={Dashboard} />
                            <Route exact path="/students" component={Students} />
                        </div>
                    </div>
                </div>
            </div>
        </div>
        </Router>
        );
    }
}

export default App;

When route is /

enter image description here

When route is /students

enter image description here

Reloading the page renders the component

Upvotes: 1

Views: 3597

Answers (2)

thecoolestguyever123
thecoolestguyever123

Reputation: 983

The Link you specified in your sidebar is trying to use the Router you wrapped the component in, not the Router you defined your links in.

This is what your sidebar component should look like.

import React, {Component} from 'react';
import {
    Link,
    withRouter
} from 'react-router-dom';
import $ from 'jquery';

class Sidebar extends Component {
        render () {
            return (
                <div>
                    <div>
                        <button className="navbar-toggler" data-toggle="collapse" data-target="#pill">
                            <span><i className="fa fa-ellipsis-v"></i> menu</span>
                        </button>
                        <div id="pill">

                            <ul className="nav nav-pills flex-column sidebar">
                                <li className="nav-item">
                                    <Link to="/" className="nav-link">
                                        <i className="fa fa-dashboard"></i> Dashboard 
                                    </Link>
                                </li>
                                <li className="nav-item">
                                    <a href="#students" className="nav-link" data-toggle="collapse">
                                        <i className="fa fa-users"></i> Students 
                                    </a>
                                    <ul className="collapse" id="students" style={{marginLeft: '-25px'}}>
                                        <li className="nav-item"><Link to="/students" className="nav-link"><i className="fa fa-eye"></i> View students</Link></li>
                                    </ul>
                                </li>

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

    }

export default withRouter(Sidebar);

More explanation: You should only wrap your top level component in the router since it for lack of better terms spawns all the children in your app. Furthermore, it will automatically inject the props for the router unless you are using redux. So unless you're using redux no need for withRouter() *.

*lmk if i'm wrong, i'm not an expert.

Example of your top level app component:

render() {
    return(
        <Router history={History}>
            <Switch>
                <Route exact path="/" component={Home} />
                <Route exact path="/student" component={Student} />
            </Switch>
        </Router>
    )
}

Upvotes: 2

Ayushya
Ayushya

Reputation: 1920

Essentially wrap your Route with Switch.

Update App.js to the below

import React, { Component } from 'react';
import Navbar from './Navbar';
import Sidebar from './Sidebar';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import Dashboard from './Dashboard';
import Students from './Students';


class App extends Component {   

    render() {     

        const { match } = this.props;
        return (
            <Router>
        <div>
            <Navbar />
            <div className="container-fluid main">
                <div className="row">
                    <div className="col-sm-2 area-left">
                        <Sidebar />
                    </div>
                    <div className="col-sm-10 area-right float-right">
                        <Switch>
                            <Route exact path="/" component={Dashboard} />
                            <Route exact path="/students" component={Students} />
                        </Switch>
                    </div>
                </div>
            </div>
        </div>
        </Router>
        );
    }
}

export default App;

Upvotes: 0

Related Questions