同形アプリのレンダリングに問題があります。react-router(1.0.0-rc3) を使用しない場合は正常に動作しますが、ルーター、特に次のようなリンクをレンダリングするコンポーネントを導入すると:
const React = require('react');
const Link = require('react-router').Link;
module.exports = class About extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<ul>
<li><Link to="/about">About</Link></li>
<li><Link to="/list">List</Link></li>
</ul>
);
}
}
出力はサーバーとクライアントで異なります。この警告が表示されます
Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) n><a class="" href="#/about" data-reacti
(server) n><a class="" href="/about" data-reactid
したがって、サーバー(またはクライアント)は href タグを別の方法でレンダリングします。これがサーバー側をレンダリングする方法です
const React = require('react');
const reactDOMServer = require('react-dom/server');
const tmpl = require('blueimp-tmpl');
const fs = require('fs');
const path = require('path');
const templateFunction = tmpl.tmpl;
const match = require('react-router').match;
const RoutingContext = require('react-router').RoutingContext;
const routes = require('../../app/routes');
const App = require('../../app/app');
const serverProps = require('../../server.props');
templateFunction.load = function(id) {
const filePath = path.resolve(serverProps.publicPath, id);
return fs.readFileSync(filePath, "utf8");
};
module.exports = function*(next) {
match({ routes, location: this.url }, (error, redirectLocation, renderProps) => {
if (error) {
this.throw(error.message);
} else if (redirectLocation) {
this.redirect(redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
const html = reactDOMServer.renderToString( <RoutingContext {...renderProps} /> );
this.body = templateFunction("index.html", html);
} else {
this.throw(404);
}
});
};
ここで使用するテンプレート エンジンは blueimp-tmpl です。最初は、レンダリング時に href-hash-sign に何かを行うのではないかと疑っていましたが、出力 renderToString をログに記録したところ、テンプレートに入る前に href-hash-sign が既になくなっています。 .
npm履歴パッケージ(react-routerのピア依存関係)を掘り下げましたが、リンクのhref部分を生成するコンポーネントのようですが、なぜそれが異なる方法でレンダリングされるのかわかりませんでした。
何か案は?
編集、これがルートです
const React = require('react');
const Router = require('react-router').Router;
const Route = require('react-router').Route;
const BaseLayout = require("./components/base-layout/base-layout");
const List = require("./components/list/list");
const About = require("./components/about/about");
module.exports = (
<Router>
<Route path="/" component={BaseLayout}>
<Route path="about" component={About} />
<Route path="list" component={List} />
</Route>
</Router>
);
BR twd