一切都是关于同构应用。我在服务器端使用int i = 9;
和React
模块进行路由,并在浏览器控制台中发出以下警告。
警告:渲染(...):用新的替换React渲染的子项 根组件。如果您打算更新此节点的子节点, 你应该让现有的孩子更新他们的状态和 渲染新组件而不是调用ReactDOM.render。
我在后端:
上定义了以下路线模式react-router
应用程序组件:
<Route path="/" component={App} >
<IndexRoute component={Home} />
</Route>
主页组件:
module.exports = React.createClass({
render : function() {
return <html>
<head></head>
<body>
<div id="container">
{ this.props.children }
</div>
<script src="/app/bundle.js"></script>
</body>
</html>
}
});
之后我使用前端:
module.exports = React.createClass({
render : function() {
return <div>Any content here</div>
}
});
可能的解决方案:
如果我理解正确,我可以将App组件呈现为静态标记(ReactDOM.render(<Home />, document.getElementById('container'));
)而将Home组件呈现为字符串(renderToStaticMarkup
),那么它就可以了。
是否可以使用renderToString
实现类似的内容?
答案 0 :(得分:3)
假设RR 1.03,您的路由配置看起来很好。
您的应用组件应如下所示:
module.exports = React.createClass({
render : function() {
return <html>
<head></head>
<body>
<div id="container">
{React.cloneElement(this.props.children,
{
anyOtherPropsHere: 'blablah'
}
)}
</div>
<script src="/app/bundle.js"></script>
</body>
</html>
}
});
您的服务器响应 - &gt;渲染应该看起来像这样。 (取自documentation)
import { renderToString } from 'react-dom/server'
import { match, RouterContext } from 'react-router'
import routes from './routes'
serve((req, res) => {
// Note that req.url here should be the full URL path from
// the original request, including the query string.
match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
// You can also check renderProps.components or renderProps.routes for
// your "not found" component or route respectively, and send a 404 as
// below, if you're using a catch-all route.
res.status(200).send(renderToString(<RouterContext {...renderProps} />))
} else {
res.status(404).send('Not found')
}
})
})
最后,在客户端加载的某个地方,做这样的事情。我在此示例中添加了history库以提供帮助。
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, match, RoutingContext } from 'react-router';
import history from 'utils/history';
import AppRoutes from '/app/AppRoutes';
// use this function to return a Route component with the right props
function createFluxComponent(Component, props) {
props = Object.assign(props, {
flux: window.flux.or.whatevs
});
return <Component {...props} />;
}
// add a global history listener perhaps?
history.listen(function(location) {
console.log('Transition to--------------', location.pathname);
});
// add window.router polyfill for transitionTo
window.router = {
transitionTo: function(t) {
return history.pushState(null, t);
}
};
// render your routing configuration, history and flux as props
ReactDOM.render(<Router createElement={createFluxComponent} history={history} routes={AppRoutes}/>, document);
最重要的是使用RouterContext渲染到字符串并在服务器端渲染道具。您可以从RR匹配函数获取renderProps,它将针对配置运行您的路由并在renderProps中生成正确的组件。然后,您只需使用Router元素向客户端呈现,并将路由器配置呈现给文档。这有意义吗?它应该没有任何不变量。