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.

Issue When Using React Router With Different Components

See original GitHub issue

Description

With the router defined in the code below, I’m attempting to have each route render the html from its specified component. My current understanding is that the “/” path should render the Base component and the IndexRoute should cause the About component to also load at the "/’ path.

NOTE: I’m using react-router 1.0.2

// Routes.jsx
import React from 'react';
import {Router, Route, IndexRoute} from "react-router";

import {Portfolio} from './components/portfolio.js';
import {About} from './components/about.js';
import {Base} from './components/base.js';
import {Blog} from './components/blog.js';
// let About = require('./components/index.js')

let Routes = (
    <Route path="/" component={Base}>
      <IndexRoute component={About} />
      <Route path="/portfolio" component={Portfolio}/>
      <Route path="/blog" component={Blog}/>
    </Route>
)

export {Routes};

Original issue (Solved):

After running webpack the website generator plugin creates static pages in the correct location but they all end up with the same html. I defined a different component to each path just as a test yet they all render the component or html from the top level route (in this case “Base”).

Below is my Entry file

entry.js

import path  from 'path';
import React from "react";
import ReactDOMServer from 'react-dom/server';
import {EventEmitter} from "events";
import { createHistory, createMemoryHistory } from 'history';
import { Router, RoutingContext, match } from 'react-router';

import {Portfolio} from './components/portfolio.js';
import {About} from './components/about.js';
import {Base} from './components/base.js';
import {Routes} from './routes.js';

module.exports = function render(locals, callback) {
  let history = createMemoryHistory(locals.path);

  let html = ReactDOMServer.renderToStaticMarkup(
    React.createElement(Router, {'history': history}, Routes )
  );

  callback(null, html);
};

Finally here is my webpack.config.js file

var path = require('path');
var webpack = require('webpack');
var data = require('./data.js');
var StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');


module.exports = {
  entry: './dev/app/entry.js',

  output: {
    filename: 'bundle.js',
    path: __dirname,
    libraryTarget: 'umd'
  },

  module: {
      loaders:[
        {
          test: /\.js$/,
          exclude: /(node_modules)/,
          loaders:['babel?presets[]=es2015,presets[]=react'],
        }
      ]
    },

  plugins: [
    new StaticSiteGeneratorPlugin('bundle.js', data.routes, data)
  ]
}

I’m not sure what I’m doing wrong. I’ve tried to follow the react router example on the README but I’m having trouble understanding exactly what the default render function is doing. How is match used ??? And the template function ??

Also, I’m unsure of how the required files are setup.

I am really looking forward to finally figuring this out. I’ve spent a long time on it. I appreciate if you are able to bring some clarification in setting things up correctly with different html components.

Please let me know if anything is unclear or additional information is needed.


Update

After some more grinding through the code I figured out my issue. I can’t say I completely understand it as some of it has to do with how React Router is written but It works. I can dive more into React Router code later if need be.

First my router top level component needed to use {{this.props.children}} in the rendered Base Component that I have referenced. This way it will also render the IndexRoute component inside of the top level or “Base” Component.

Next I needed to change my render function to look like this. I wasn’t using

<RoutingContext {...renderProps} />

Also the es6 destructuring syntax was not as it should be considering how I had my routes component being imported. I simply changed {Routes, location} to {routes: Routes, location}.

New Entry.js file

import path  from 'path';
import React from "react";
import ReactDOMServer from 'react-dom/server';
import {EventEmitter} from "events";
import { createHistory, createMemoryHistory } from 'history';
import { Router, RoutingContext, match } from 'react-router';
import Routes from './routes.js';


// version with match...
module.exports = function render(locals, callback) {
  let history = createMemoryHistory(locals.path);
  let location = history.createLocation(locals.path);

  match( { routes:Routes, location:location }, (error, redirectLocation, renderProps) => {

    function generateHTML() {
      return ReactDOMServer.renderToStaticMarkup(
        <RoutingContext {...renderProps} />
      )
    }

    callback(null, generateHTML());
  })

};

New Problem

How do I setup “live reloading” with scss that is being applied to the statically generated components? Currently I have my styles being extracted into a separate css file. Unfortunately I’ve read that there is no support for hot reloading the styles this way… How do I setup hot reloading with scss that needs to be applied to components that will be statically rendered ? Keep in mind I tried using the traditional method of style!css!sass loader but I run into the issue of the Window not being defined because it executes before its in the browser environment. Suggestions / solutions welcomed. Right now I have to manually refresh my page to style the react components being statically rendered.

Issue Analytics

  • State:open
  • Created 8 years ago
  • Comments:7

github_iconTop GitHub Comments

1reaction
TerrellVcommented, Dec 18, 2015

@VaclavSynacek I did it because it was the most relevant example I could find. Thank you for including the link. How would one process sass and apply it via the style-loader in such a configuration? I figured out how to do this with the browser/client side js but I get errors for obvious reasons when I try and require those styles in the react components that get converted to static html.

What’s the best way to process sass and apply it to the components being rendered statically ? Because of the situation is the only option to use ExtractTextPlugin ? Id really like to use styl-loader for its development benefits but it requires the window.

0reactions
cusxiocommented, Dec 19, 2015

That is pretty much it, but when your on development, you have to find a way to render to the dom.

This blog post explains pretty much the problems you are facing and how to use React to solve it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Problems with React router doesn't load the routes of ...
The issue is with how you've declared the root route paths, both are only matched when the URL path is exactly "/" or...
Read more >
Primary Components - React Router v5
Primary Components. There are three primary categories of components in React Router: routers, like <BrowserRouter> and <HashRouter>; route matchers, ...
Read more >
How To Handle Routing in React Apps with React Router
In this tutorial, you'll install and configure React Router, build a set of routes, and connect to them using the <Link> component.
Read more >
How to Handle Routing in a React Application using the React ...
To do this, we make use of other important components from the react-router-dom . The Switch and the Route components. Go inside the...
Read more >
React Router DOM: How to handle routing in web apps
In other words, the router components for an app development environment using React Native. React Router DOM enables you to implement ...
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