35

私はreact-router 4を使用してサーバー側のレンダリングを試みています。ここで提供されている例に従っていますhttps://reacttraining.com/react-router/web/guides/server-rendering/putting-it-all-together

サーバーの例に従って、使用する必要がありますStaticRouter。例に従ってインポートすると、StaticRouter が未定義として表示されます

import {StaticRouter} from 'react-router';

オンラインでいくつかの調査を行った後、使用できることがわかりましreact-router-domた。これで、インポート ステートメントは次のようになります。

import {StaticRouter} from 'react-router-dom';

ただし、コードを実行するInvariant Violation: Browser history needs a DOMと、ブラウザーに表示されます。

私のserver.jsファイルコード

....
app.get( '*', ( req, res ) => {
  const html = fs.readFileSync(path.resolve(__dirname, '../index.html')).toString();
  const context = {};
  const markup = ReactDOMServer.renderToString(
    <StaticRouter location={req.url} context={context} >
      <App/>
    </StaticRouter>
  );

  if (context.url) {
    res.writeHead(302, {
      Location: context.url
    })
    res.end();
  } else {
      res.send(html.replace('$react', markup));
  }
} );
....

そして私の client/index.js コード

....
ReactDOM.render((
  <BrowserRouter>
    <App />
  </BrowserRouter>
), root);
....

Update v1 私の例を最小限に減らしても、同じエラーが発生します。

clientIndex.js

import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from '../App'

ReactDOM.render((
  <BrowserRouter>
    <App/>
  </BrowserRouter>
), document.getElementById('app'))

serverIndex.js

import { createServer } from 'http'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router'
import App from '../App'

createServer((req, res) => {
  const context = {}

  const html = ReactDOMServer.renderToString(
    <StaticRouter
      location={req.url}
      context={context}
    >
      <App/>
    </StaticRouter>
  )

res.write(`
  <!doctype html>
  <div id="app">${html}</div>
`)
res.end()
}).listen(3000);

App.js

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import routes from "./client/routes";
const App = ( ) => (
  <Router>
    <Route path="/" exact render={( props ) => ( <div>Helloworld</div> )} />
  </Router>
)

export default App;
4

3 に答える 3