我在渲染同构应用程序时遇到问题,当我不使用 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