Having trouble with React router and Meteor

Hey guys,

So far I’ve gotten on really well with Meteor and React but I felt my routing was messy so tried starting from scratch again, trouble is I’ve come up against something I can’t seem to fix. It’s probably something super simple that I’m forgetting to do so any help would be greatly appreciated.

I’ve got an app with 3 main areas, sidebar, content and footer.

The navigation links are located in the sidebar, which when clicked should only reload the content section and the components within it.

The way I’ve got it set up right now, it works as expected, loading the correct pages if I visit the URL directly, but when I click them from the sidebar nothing happens (apart from the history bar updating with the new url). But nothing is actually being rendered in the browser.

Here’s a look at the layout - I’ve stripped it to the very basics for readability :

main.js

import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

import App from './../imports/components/app.js';

import './main.html';

Meteor.startup(() => {
  render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('App'));
});

app.js

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

import Sidebar from './sidebar';
import Footer from './footer';

import Home from './home';
import Page2 from './page2';

import NoMatch from './404';

class App extends Component {
  render() {
    return (
      <div>
        <Sidebar />
        <BrowserRouter>
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/page2" component={Page2} />
            <Route component={NoMatch} />
          </Switch>
        </BrowserRouter>
        <Footer />
      </div>
    );
  }
}

export default App;

sidebar.js

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

class Sidebar extends Component {

  render() {
    return (
      <div>
        <h1>SIDEBAR</h1>
        <ul>
          <li>
            <NavLink to="/">Home</NavLink>
          </li>
          <li>
            <NavLink to="/page2">Page 2</NavLink>
          </li>
        </ul>
      </div>
    );
  }
}

export default Sidebar;

page2.js

import React, { Component } from 'react';

class Page2 extends Component {

  render() {
    return (
      <div>
        THIS IS PAGE 2
      </div>
    );
  }
}

export default Page2;

Can you see where I’m going wrong?

I worked it out…

Just in case any other newbs are getting stuck here…

import { withRouter } from 'react-router';

and then export with it too :

export default withRouter(App);

So in my code above app.js becomes :

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

import Sidebar from './sidebar';
import Footer from './footer';

import Home from './home';
import Page2 from './page2';

import NoMatch from './404';

class App extends Component {
  render() {
    return (
      <div>
        <Sidebar />
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/page2" component={Page2} />
            <Route component={NoMatch} />
          </Switch>
        <Footer />
      </div>
    );
  }
}

export default withRouter(App);
1 Like

It seems you should never nest Routers within routers.

Maybe removing it from here would’ve worked as well, im not sure though :thinking:

Whoops, yeah forgot to say that I also removed the BrowserRouter from app.js too.

The entire app gets wrapped with BrowserRouter when rendering, it’s now the only time BrowserRouter is used :

main.js

Meteor.startup(() => {
  render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('App'));
});