我有一个特殊情况,我希望在保持应用程序通用/同构的同时加载不同的路由而不是初始请求路由。
所以我有一些像这样的路线
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="potato" component={Potato}/>
<Route path="apple" component={Apple}/>
</Route>
</Router>
在服务器的初始请求中,服务器根据其他地方的其他信息决定应该加载其他路由,即应该呈现苹果路由,但前端的url应该保留/
首先,这非常简单,因为您可以更改提供的匹配
的网址match({ routes, location: url }, (error, redirectLocation, renderProps) => {
但是,客户端首先正确显示,然后在加载原始请求路由后几秒钟而不是服务器决定的路径。 它会显示如下错误
警告:React尝试在容器中重用标记,但校验和无效。这通常意味着您正在使用服务器呈现,并且在服务器上生成的标记不是客户端所期望的。 React注入了新的标记以补偿哪些有效但你已经失去了服务器渲染的许多好处。相反,弄清楚为什么生成的标记在客户端或服务器上是不同的:
这是有意义的,因为我告诉服务器在/ route被击中时渲染/ apple。但是当它到达客户端时,它就会发现路由是/但是标记显示的内容与应该存在的内容不同。
那么无论如何我可以欺骗客户,一切都很好并且正确吗?
一种解决方案就是进行301重定向,但这意味着客户端 将最终显示/苹果而不仅仅是/在网址中
我想避免使用301 for SEO并保留用户输入的初始网址
这个疯狂的请求的任何解决方案?
我正在使用
反应:15.0.2
react-router:2.4.0
反应-终极版:4.1.2
redux:3.1.2
答案 0 :(得分:0)
您可以在调用match
之前在服务器上定义路由,然后让客户端在客户端上接收它们。
服务器上有这样的东西:
function getRoutes(something) {
if (something === 'apple') {
return (
<Route path="/" component={Apple}>
<Route path="potato" component={Potato}/>
</Route>
);
}
return (
<Route path="/" component={App}>
<Route path="potato" component={Potato}/>
<Route path="apple" component={Apple}/>
</Route>
);
}
const routes = getRoutes('apple');
<script dangerouslySetInnerHTML={{__html: `window.__INITIAL_ROUTES__ = ${routes}`}}></script>
<Router history={createMemoryHistory()}>
{routes}
</Router>
......并在客户端:
const routes = window.__INITIAL_ROUTES__;
<Router history={browserHistory}>
{routes}
</Router>