question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Any help / turorials on how the router works in this specific kit?

See original GitHub issue

It seems to be that the router in this project isn’t configured the same standard way all the tutorials and documentation out there do.

e.g. server.js uses a dispatch event, I can’t find any sample code elsewhere that uses this method, even in the API docs for react-router.

server.get('*', async (req, res, next) => {
    ...

    await Router.dispatch({ path: req.path, context }, (state, component) => {
      data.body = ReactDOM.renderToString(component);
      data.css = css.join('');
    });

    const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);
    res.status(statusCode).send('<!doctype html>\n' + html);

  ...
});

I’m trying to configure the router to load routes lazily in a similar way to this example project.

In that huge-apps example code you can asynchonouly chose which routes to load in a route config

module.exports = {
  path: 'course/:courseId',

  getChildRoutes(location, cb) {
    require.ensure([], (require) => {
      cb(null, [
        require('./routes/Announcements'),
        require('./routes/Assignments'),
        require('./routes/Grades')
      ])
    })
  },

  ...
}

I can’t figure out how to apply the same thing to the way routing is done in this starter kit, anyone got similar experiences or can share their knowledge?

<bountysource-plugin>

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource. </bountysource-plugin>

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:24 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
AlastairTaftcommented, Oct 7, 2017

EDIT: Make sure you install the latest version of react-router with npm install react-router@latest, I think npm install react-router will instead install version 0.13.x.

I did do, I’ll try and summarise and strip down my files so you can make use of them. There’s three main files I had to change, app.js, server.js and routes.js. You’ll probably have to edit them a bit to get them to work, but the jist of it is there (bare in mind this is a work in progress).

routes.js

import React from 'react';
import { Router, Route, IndexRoute } from 'react-router'

const routes = 
  <Route path="/" component={App}>
    <IndexRoute onEnter={redirectToLogin} component={LandingPage} />
    <Route path="callback" component={ CallbackRedirect } />
    <Route path="panel" component={ ControlPanel }>
      <Route path="content" component={ ContentOverview } />
      <Route path="site-type-selection" component={ SiteTypeSelection } />
      <Route path="create" component={ CreateContent } />
      <Route path="site-settings" component={ SiteSettings } />
      <Route path="edit/:contentId" component={ EditContent } />
    </Route>
  </Route>

export default routes

I heavily stripped out the server.js and app.js just to get something working for now, might still be some dead code in there.

With the new server.js file you won’t be able to use the decorators @withContext and @withStyles, this is because it requires a post back to update the css which defeats a lot of the benefits of react-router. For my solution I converted all css to inline styles as pointed out here, you may find a different way to do it. If you need to do media queries a good alternative is to use the @withViewport decorator that already exists, then in your render method check this.props.viewport.width. See here for more info on server routing.

server.js

server.get('*', async (req, res, next) => {
  try {
    const context = {
      jwt: req.session.jwt
    };

    match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
      if (error) {
        res.status(500).send(error.message)
      } else if (redirectLocation) {
        res.redirect(302, redirectLocation.pathname + redirectLocation.search)
      } else if (renderProps) {
        var content = renderToString(
          <Html 
            body={renderToString(<AuthRoutingContext jwt={req.session.jwt} {...renderProps} />)} 
            css=""
          />
        )
        res.status(200).send(content)
      } else {
        res.status(404).send('Not found')
      }
    })

  } catch (err) {
    next(err);
  }
});

I’m using a jwt token for my user authentication so I like having this readily available in the context. To do this I had to extend the react-router RoutingContext class and add it in. You can skip this if you don’t want a context and just use the default RoutingContext class in your server.js file instead. Open to suggestions on other ways to handle this.

AuthRoutingContext.js

import React, { PropTypes, Component } from 'react'
import {RoutingContext} from 'react-router'

export default class AuthRoutingContext extends RoutingContext {
  static propTypes = {
    jwt: React.PropTypes.string
  }

  static childContextTypes = {
    history: React.PropTypes.object.isRequired,
    location: React.PropTypes.object.isRequired,
    jwt: React.PropTypes.string
  }

  getChildContext() {
    const { history, location, jwt } = this.props
    return { history, location, jwt }
  }
}

For the app.js I actually used the same method as the server.js, even though the documentation encourages you not to however I couldn’t find a way using the normal method to include my jwt token in the context. EDIT: Don’t do this client side, I have a feeling this is why my links don’t work.

app.js

/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import 'babel-core/polyfill';
import React from 'react'
import { render } from 'react-dom'
import FastClick from 'fastclick';
import {Router, match} from 'react-router'
import routes from './routes';
import Location from './core/Location';
import { addEventListener, removeEventListener } from './utils/DOMUtils';
import AuthRoutingContext from './components/AuthRoutingContext'

import injectTapEventPlugin from 'react-tap-event-plugin'
injectTapEventPlugin()

let cssContainer = document.getElementById('css');
const appContainer = document.getElementById('app');

function run() {
  let currentLocation = null;
  let currentState = null;

  // Make taps on links and buttons work fast on mobiles
  FastClick.attach(document.body);

  match({ routes, location: window.location.pathname }, (error, redirectLocation, renderProps) => {
    if (error) {
      throw error
      //res.status(500).send(error.message)
    } else if (redirectLocation) {
      throw new Error('Redirect not handled')
      //res.redirect(302, redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
      //console.log(require('util').inspect(renderProps))
      render(<AuthRoutingContext jwt={localStorage.getItem('jwt')} {...renderProps} />, appContainer) 
    } else {
      throw new Error('Not found')
    }
  })

}

// Run the application when both DOM is ready
// and page content is loaded
if (window.addEventListener) {
  window.addEventListener('DOMContentLoaded', run);
} else {
  window.attachEvent('onload', run);
}

Open to ideas if anyone’s got better ways of handling stuff.

0reactions
langpavelcommented, Oct 7, 2017

I see no reason why keep this open 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is a Router? How do Routers work? - InetDaemon.Com
This network certification tutorial on routers focuses on identifying network routers, and explaining the functions of routers provide. This ...
Read more >
How to Setup and Configure your Home Router
In this tutorial I will explain the various ports available on most routers, and how to set up your router and change common...
Read more >
How to Build a Raspberry Pi Router - Step by Step Tutorial
When you use other firmware for a router, it often comes with a fixed set of capabilities. On the other hand, OpenWRT provides...
Read more >
How to Set Up a Wireless Network From Start to Finish
Setting up a Wireless Router or fast WiFi Network in your home is ... of how a wireless network works that will help...
Read more >
About Routers: Types of Routers, Routing Table and IP Routing
As the name is self-explanatory, routers acquire their nomenclature from the work they perform, means they do routing of data packets from ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found