React-Router V4 Rendering Blank

#1

I am building a web app on Meteor and trying to implement routing using React-Router v4. I set up a basic routing structure following React-Router V4 documentation to the best of my understanding, however, no pages of my app render.

The console does not throw any errors when I run my app; however nothing renders, not even the landing page, which would otherwise render if there was no routing implemented. For some reason, therefore, my routing code is causing the app to render a blank page, despite App.js not being empty. Furthermore, as a test, if I type in an arbitrary route (i.e. ‘localhost:3000/randomroute’), I am not thrown an error saying that it is not a valid route. Nothing happens in the console.

Below are the relevant code snippets.

routes.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, BrowserRouter} from 'react-router-dom';
import { render } from 'react-dom';
import { App } from './App.js';


Meteor.startup(() => {
  ReactDOM.render(
    <BrowserRouter>
      <Route exact path="/" component={App}/>
    </BrowserRouter>,
     document.getElementById('render-target')
   );
});

main.js

import React, { Component } from 'react';
import {Meteor} from 'meteor/meteor';
import { render } from 'react-dom';

import '../imports/client/routes';

main.html

<head>
  <title>React Meteor Voting</title>
</head>

<body>
  <div id="render-target">

  </div>
</body>

App.js

import React, { Component } from 'react';
import { createContainer } from 'meteor/react-meteor-data';
import Item from '../client/Item';

import AccountsUIWrapper from '../ui/AccountsUIWrapper.js';
import Items from '../api/Items';


 class App extends Component {
   addItems(event) {
     event.preventDefault();
     const itemOne = this.refs.itemOne.value.trim();
     const itemTwo = this.refs.itemTwo.value.trim();
     if (itemOne != '' && itemTwo != '') {
    Meteor.call('insertNewItem', itemOne, itemTwo, (err, res) => {
      if (!err) {
        this.refs.itemOne.value = '';
        this.refs.itemTwo.value = '';
      }
    });
       this.refs.itemOne.value = '';
       this.refs.itemTwo.value = '';
      }
     }

showAll() {
  if(this.props.showAll) {
  Session.set('showAll', false);
} else  {
Session.set('showAll', true);
}
}



  render() {
    if (!this.props.ready) {
        return <div>Loading</div>
    }


    return (
    <div>
      <header>
        <h1>Level Up Voting</h1>
        <AccountsUIWrapper />
        <button onClick={this.showAll.bind(this)}>
          Show {this.props.showAll ? 'One' : 'All'}</button>
      </header>
        <main>
          <form className='new-items' onSubmit={this.addItems.bind(this)}>
            <input type='text' ref='itemOne' />
            <input type='text' ref='itemTwo'/>
            <button type='submit'> Add Items </button>
          </form>
            {this.props.items.map((item) => {
              return <Item item={item} key={item._id}/>
            } )}
        </main>

      </div>
    );
  }
}

export default createContainer(() => {
  let itemsSub = Meteor.subscribe('allItems');
  let showAll = Session.get('showAll');
  return{ showAll,
    ready: itemsSub.ready(),
    items: Items.find({}, {
      limit: showAll ? 50 : 1,
      sort: { lastUpdated: 1}
    }).fetch()
  }
}, App);

Package.json

    {
  "name": "votingAppReact",
  "private": true,
  "scripts": {
    "start": "meteor run"
  },
  "dependencies": {
    "babel-runtime": "^6.26.0",
    "bcrypt": "^1.0.3",
    "classnames": "^2.2.5",
    "history": "^4.7.2",
    "meteor-node-stubs": "^0.3.2",
    "react": "^16.2.0",
    "react-addons-pure-render-mixin": "^15.6.2",
    "react-dom": "^16.2.0",
    "react-komposer": "^2.0.0",
    "react-router": "^4.2.0",
    "react-router-3": "^3.2.2",
    "react-router-dom": "^4.2.2"
  }
}

Any help is appreciated, please let me know if you would like additional information!

#2

If you haven’t checked it out yet, maybe this App/router setup can help you find the issue. Also you have to include a route for not found as the last route to get that error page for invalid routes. https://github.com/cleverbeagle/pup/blob/master/imports/ui/layouts/App/App.js

#3

Hey, I am trying to reproduce a similar situation based on the code snippet you provided. So far couldn’t managed to do that :confused: Unfortunately the routing still works for me based on the snippet you provided.

However, there are a couple of stuff I want to mention. Maybe pointing out them might help you to solve your problem (maybe not but worth a shot)

As npm’s official documentation also suggests

Sometimes npm’s cache gets confused

Which can cause weird problems.

When I check your package.json file I see the following packages

"dependencies": {
    ...
    "history": "^4.7.2",
    "react-router": "^4.2.0",
    "react-router-3": "^3.2.2",
    "react-router-dom": "^4.2.2"
    ...
  }

I don’t know whether you really need all these packages at the same time but let’s check whether you really need them or not

For react-router, the official documentation suggests

Note: This package provides the core routing functionality for React Router, but you might not want to install it directly. If you are writing an application that will run in the browser, you should instead install react-router-dom

So maybe you can first start by deleting this package if you really don’t need it

For history package, do you use it directly in anywhere ?

Because when you check react-router-dom, history package is one of it’s dependency already

"dependencies": {
    "history": "^4.7.2"
}

So if you are not using history in your code, maybe you can also get rid of it.

For react-router-3, this one is a former version of react-router v4 which can be installed via npm i react-router-dom. So this is more like an either/ or situation. If you want to implement react-router-3 then you can delete react-router-dom but if you want to use an up to date version, you should get rid of react-router-3

Because when you check their dependencies, react-router-dom's dependencies are

"dependencies": {
    "history": "^4.7.2",
    "invariant": "^2.2.2",
    "loose-envify": "^1.3.1",
    "prop-types": "^15.5.4",
    "react-router": "^4.2.0",
    "warning": "^3.0.0"
  },

However, react-router-3s dependencies are

"dependencies": {
    "create-react-class": "^15.5.1",
    "history": "^3.0.0",
    "hoist-non-react-statics": "^2.3.1",
    "invariant": "^2.2.1",
    "loose-envify": "^1.2.0",
    "prop-types": "^15.5.6",
    "warning": "^3.0.0"
  },

See react-router-3 is using an old version of history, however react-router-dom is using a new version. And also you have history as your direct dependency.

When you do the cleaning, you should do rm -rf node_modules first to make sure that the cache is also gone. Then you can do a fresh npm i and see if it’s gonna work or not.

As I said, this is just a guess as I cannot reproduce the problem. Maybe there is something else that I missed. Let’s also hope someone else notice anything different that might be helpful :slight_smile: