Ошибки рендеринга на стороне сервера React Router: Предупреждение: Ошибка propType: Требуемая опора `history` не была указана в` RoutingContext`

Я настраиваю простое игрушечное приложение для изучения React / Hapi, и все работает хорошо, пока я не попробую настроить маршрутизацию на стороне сервера. Сервер работает без ошибок и правильно отображает "/" с hello world.

Однако, когда я перехожу к «/ test», я получаю следующие ошибки.

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`.

Где я здесь ошибаюсь?

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>
);

Потому что их просили

Клиент 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'));

Клиентский маршрутизатор

 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>
);

person trattles    schedule 28.12.2015    source источник
comment
Как выглядит ваш клиентский код рендеринга? Это ошибки на стороне клиента? Или ошибки на стороне сервера?   -  person Brandon    schedule 29.12.2015
comment
Я добавил в сообщение Client Entry и Client Router. Я считаю, что они на стороне сервера? Хотя у меня есть эта ошибка в моей консоли Предупреждение: React.createElement: type не должен быть нулевым, неопределенным, логическим или числом. Это должна быть строка (для элементов DOM) или ReactClass (для составных компонентов).   -  person trattles    schedule 29.12.2015


Ответы (1)


Вам необходимо передать history в качестве опоры для Router на клиенте:

export default (
    <Router history={history}>
        <Routes />
    </Router>
);

Вероятная проблема с вашим серверным кодом заключается в том, что вы неправильно передаете маршруты к match. Ожидается свойство с именем routes, а не Routes. Попробуй это:

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

Особенно обратите внимание на это утверждение из документация:

If all three parameters are undefined, this means that there was no route found matching the given location.
person Brandon    schedule 28.12.2015
comment
Когда я это делаю, я все равно получаю те же ошибки: Предупреждение: Failed propType: Требуемая опора history не была указана в RoutingContext. Предупреждение: Failed propType: Требуемое свойство location не было указано в RoutingContext. Предупреждение: Failed propType: Требуемое свойство routes не было указано в RoutingContext. Предупреждение: Failed propType: Требуемый prop params не был указан в RoutingContext. Предупреждение: Failed propType: обязательный параметр components не был указан в RoutingContext. - person trattles; 29.12.2015
comment
в консоли браузера или на вашем сервере? - person Brandon; 29.12.2015
comment
Это ошибки на стороне сервера. Кажется, что маршрутизация на сервере ничего не передает для renderprops? - person trattles; 29.12.2015
comment
Вы были совершенно правы насчет проблемы с указанным параметром. В документации по рендерингу на стороне сервера реактивного маршрутизатора об этом вообще не упоминалось. Это научит меня не копаться в реальных функциях: / Большое спасибо за вашу помощь! - person trattles; 29.12.2015