Ejaz
Ejaz

Reputation: 1632

React Router - Routes in different components

My app is something like below, I have a two components - App and Home I can go from App to Home, but in the Home component there are two other routes - Profile and Quotes.

On clicking the links for profile and quotes, I don't get any exception, and neither does it load that component.

However if I move the routes to the App component, then it loads profile and quotes just fine.

What could be the issue here. Please guide.

The App component is below -

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

class App extends React.Component {
    state = { //...some vals }

    render() {
        return (
          <div>
            <Link to='/home'>Home</Link>
            <Switch>
              <Route exact path='/home' component={Home}/>
            </Switch>   
          </div>    
        )
    }
}

export default App

The Home component is below -

import React, { Fragment } from 'react';
import { Route, Link, Switch } from 'react-router-dom'
import Profile from './Profile';
import Quotes from './Quotes';

class Home extends React.Component {
    state = { //...some vals }

    render() {
        return (
          <Fragment>
            <Link to='/profile'>Profile</Link>
            <Link to='/quotes'>Quotes</Link>
            <Switch>
              <Route exact path='/profile' component={Profile}/>
              <Route exact path='/quotes' component={Quotes}/>  
            </Switch>
          </Fragment>   
        )
    }
}

export default Home

And in the index.js as below -

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom'


ReactDOM.render(
    <BrowserRouter><App /></BrowserRouter>,
     document.getElementById('root')
);

Upvotes: 1

Views: 3219

Answers (3)

Praneeth Paruchuri
Praneeth Paruchuri

Reputation: 1032

When you use routes in a component, it needs to be wrapped with a Router component. BrowserRouter in your case.

So, when you add routes to Home component, you need to do the same there.

But there will be an issue with that. Both the Routers are independent of each other and have a different history object.

This not a fix, you shouldn't be doing this. This is just for you to understand better:

import React, { Fragment } from "react";
import { BrowserRouter, Route, Link, Switch } from "react-router-dom";
import Profile from "./Profile";
import Quotes from "./Quotes";

class Home extends React.Component {
  state = {}; //...some vals }

  render() {
    return (
      <BrowserRouter>
        <Fragment>
          <Link to="/profile">Profile</Link>
          <Link to="/quotes">Quotes</Link>
          <Switch>
            <Route exact path="/profile" component={Profile} />
            <Route exact path="/quotes" component={Quotes} />
          </Switch>
        </Fragment>
      </BrowserRouter>
    );
  }
}

export default Home;

Check out the Home component and console of the Quotes component for the history object.

Edit mystifying-bash-ll666

Upvotes: 3

Piyush Bhati
Piyush Bhati

Reputation: 956

Remove exact from home <Route in App file.

App.js

<Route path='/home' component={Home}/>

use exact only when there is no child route associated with it otherwise it will not route to children route.

Update Home.js

Add /home in Home.js Route and Link

import React, { Fragment } from 'react';
import { Route, Link, Switch } from 'react-router-dom'
import Profile from './Profile';
import Quotes from './Quotes';

class Home extends React.Component {
    state = { //...some vals }
    render() {
        return (
          <Fragment>
            <Link to='/home/profile'>Profile</Link>
            <Link to='/home/quotes'>Quotes</Link>
            <Switch>
               <Route exact path='/home/profile' component={Profile}/>
               <Route exact path='/home/quotes' component={Quotes}/>  
            </Switch>
          </Fragment>   
    )
  }
}

export default Home

I hope this will solve your problem.

Upvotes: -1

Muhammad Zia
Muhammad Zia

Reputation: 88

You need to do something like :

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

import Home from "../components/Home";
// import your other pages/components here

const renderRoutes = () => {
  return (
    <Router>
      <div>
        <Switch>
          <Route
            exact
            path="/"
            render={props => (
              <AppRoute Component={Home} props={props} />
            )}
          />
        </Switch>
      </div>
    </Router>
  );
};

const AppRoute = ({ Component, Layout, props }) => {
  if (Layout) {
    return (
      <Layout {...props}>
        <Component {...props} />
      </Layout>
    );
  }

  if (!Component) {
    return <Layout {...props} />;
  }

  return <Component {...props} />;
};

export default renderRoutes;

And in your App.js file:

import React from 'react';
import RenderRoutes from './routes';

class App extends React.Component {
    constructor (props) {
        super(props);
    }

    render () {
        return (
            <div>
                <RenderRoutes/>
            </div>
        );
    }
}

export default App;

What you are doing now is making routes on a global level and you can use {NavLink} or {Link} anywhere in your app, start making routes by <Route exact path="/" render={props => (<AppRoute Component={Home} props={props} />)}/>
Just import your component and put it in Component={YourComponent} and add the path whatever you want to call it like path="/Home/Profiles"
Checkout this starter-kit on GitHub

Upvotes: 0

Related Questions