I'm setting up a simple toy app to learn React/Hapi and everything is working well till I try and set up serverside routing. The server runs without error and renders "/" properly with hello world.
However when I navigate to "/test" I get the following errors.
Warning: Failed propType: Required prop `history` was not specified in `RoutingContext`.
Warning: Failed propType: Required prop `location` was not specified in `RoutingContext`.
Warning: Failed propType: Required prop `routes` was not specified in `RoutingContext`.
Warning: Failed propType: Required prop `params` was not specified in `RoutingContext`.
Warning: Failed propType: Required prop `components` was not specified in `RoutingContext`.
Where am I going wrong here?
Server.js
'use strict';
const Hapi = require('hapi');
const Path = require('path');
const server = new Hapi.Server();
server.connection({ port: 3000});
//React Junk
import React from 'react';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import { renderToString } from 'react-dom/server';
import reducer from './../common/Reducers/index.js';
import { match, RoutingContext } from 'react-router';
import Routes from './../common/routes/Routes.js';
const handleRender = function(req, res) {
const store = createStore(reducer);
match({Routes, location: req.url}, (error, redirectLocation, renderProps) => {
//res(req.url);
if(error) {
res(error.message);
}
else {
const html = renderToString(
<Provider store={store}>
<RoutingContext {...renderProps} />
</Provider>
);
const initialState = store.getState();
res(renderFullPage(html, initialState));
}
});
// const html = renderToString(
// <Provider store={store}>
// <App />
// </Provider>
// );
// const initialState = store.getState();
// res(renderFullPage(html, initialState));
}
const renderFullPage = function(html, initialState) {
return `
<!doctype html>
<html>
<head>
<title>Please Work</title>
</head>
<body>
<div id="app-mount">${html}</div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}
</script>
<script src="/static/bundle.js"></script>
</body>
</html>
`;
}
server.register(require('inert'), (err) => {
server.route({
method: 'GET',
path: '/static/{filename}',
handler: function (req, reply) {
reply.file('static/' + req.params.filename);
}
})
server.route({
method: 'GET',
path: '/',
handler: function(req, res) {
res('hello world');
}
});
server.route({
method: 'GET',
path: '/{path*}',
handler: function(req, res) {
handleRender(req, res);
}
})
server.start(() => {
console.log('Server running at:', server.info.uri);
})
})
Routes.js
import { Route } from 'react-router';
//Components
import App from './../components/App.jsx';
import Name from './../components/Name.jsx';
export default (
<Route path="/" component={App}>
<Route path="test" component={Name} />
</Route>
);
Because they were asked for
Client entry.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import App from './../common/components/App.jsx';
import Router from './../common/routes/Router.jsx';
import reducers from './../common/Reducers';
const initialState = window.__INITIAL_STATE__;
const store = createStore(reducers(initialState));
ReactDOM.render(
<Provider store={store}>
<Router />
</Provider>
, document.getElementById('app-mount'));
Client Router
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route } from 'react-router';
import createHashHistory from 'history/lib/createHashHistory';
const history = createHashHistory();
import Routes from './Routes.js';
export default (
<Router history={history}>
<Routes />
</Router>
);
You need to pass history
as a prop to Router
on the client:
export default (
<Router history={history}>
<Routes />
</Router>
);
The likely problem with your server-code is that you aren't passing the routes to match
correctly. It expects a property named routes
, not Routes
. Try this:
match({routes: Routes, location: req.url}, (error, redirectLocation, renderProps) => {
Especially note this statement from the documentation:
If all three parameters are undefined, this means that there was no route found matching the given location.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With