Issue When Using React Router With Different Components
See original GitHub issueDescription
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:
- Created 8 years ago
- Comments:7

Top Related StackOverflow Question
@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.
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.