ReactJS反应路由器服务器渲染问题
一切都是关于同构应用。我在服务器端使用React
与react-router
模块进行路由,并在浏览器控制台中发出以下警告。ReactJS反应路由器服务器渲染问题
警告:渲染(...):用新的 根组件替换呈现React渲染的子项。如果您打算更新此节点的子节点 ,则应该让现有子节点更新其状态,并且 会呈现新组件而不是调用ReactDOM.render。
<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>
}
});
我在使用之后前端:
ReactDOM.render(<Home />, document.getElementById('container'));
可能的解决方案: 如果我理解正确,如果我可以使应用程序组件作为静态标记(renderToStaticMarkup
)和家庭组成的字符串(renderToString
),那么这将是确定。
是否可以通过react-router
实现类似的功能?
假设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>
}
});
你的服务器响应 - >渲染应该是这个样子。 (从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元素和路由器配置将客户端呈现给文档。这有意义吗?它应该没有任何不变地工作。
谢谢,它帮助我解决了我的问题! –
如果答案有帮助,您能否将其标记为已接受? – nacmartin
你是否搜索过“同构反应”? –
@HenrikAndersson很多 –
我想用React呈现App组件,而不是使用纯html。 –